X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/b7b97e7726ecfcc6d1ea545dd1d5707d4a9d0307..d2ebf0b7303be387d2d5a55ea0cd672fdf0c4f25:/src/common/intl.cpp diff --git a/src/common/intl.cpp b/src/common/intl.cpp index c5d9ede220..d3823ead81 100644 --- a/src/common/intl.cpp +++ b/src/common/intl.cpp @@ -887,7 +887,8 @@ public: wxPluralFormsCalculatorPtr& rPluralFormsCalculator); // fills the hash with string-translation pairs - void FillHash(wxMessagesHash& hash, bool convertEncoding) const; + void FillHash(wxMessagesHash& hash, const wxString& msgIdCharset, + bool convertEncoding) const; private: // this implementation is binary compatible with GNU gettext() version 0.10 @@ -963,7 +964,8 @@ class wxMsgCatalog { public: // load the catalog from disk (szDirPrefix corresponds to language) - bool Load(const wxChar *szDirPrefix, const wxChar *szName, bool bConvertEncoding = FALSE); + bool Load(const wxChar *szDirPrefix, const wxChar *szName, + const wxChar *msgIdCharset = NULL, bool bConvertEncoding = false); // get name of the catalog wxString GetName() const { return m_name; } @@ -1076,7 +1078,7 @@ bool wxMsgCatalogFile::Load(const wxChar *szDirPrefix, const wxChar *szName0, FIXME: UNICODE SUPPORT: must use CHARSET specifier! */ wxString szName = szName0; - if(szName.Find(wxT('.')) != -1) // contains a dot + if(szName.Find(wxT('.')) != wxNOT_FOUND) // contains a dot szName = szName.Left(szName.Find(wxT('.'))); wxString searchPath = GetFullSearchPath(szDirPrefix); @@ -1106,7 +1108,7 @@ bool wxMsgCatalogFile::Load(const wxChar *szDirPrefix, const wxChar *szName0, wxString strFullName; if ( !wxFindFileInPath(&strFullName, searchPath, strFile) ) { wxLogVerbose(_("catalog file for domain '%s' not found."), szName.c_str()); - return FALSE; + return false; } // open file @@ -1115,18 +1117,18 @@ bool wxMsgCatalogFile::Load(const wxChar *szDirPrefix, const wxChar *szName0, wxFile fileMsg(strFullName); if ( !fileMsg.IsOpened() ) - return FALSE; + return false; // get the file size off_t nSize = fileMsg.Length(); if ( nSize == wxInvalidOffset ) - return FALSE; + return false; // read the whole file in memory m_pData = new size_t8[nSize]; if ( fileMsg.Read(m_pData, nSize) != nSize ) { wxDELETEA(m_pData); - return FALSE; + return false; } // examine header @@ -1146,7 +1148,7 @@ bool wxMsgCatalogFile::Load(const wxChar *szDirPrefix, const wxChar *szName0, wxLogWarning(_("'%s' is not a valid message catalog."), strFullName.c_str()); wxDELETEA(m_pData); - return FALSE; + return false; } // initialize @@ -1214,23 +1216,33 @@ bool wxMsgCatalogFile::Load(const wxChar *szDirPrefix, const wxChar *szName0, return true; } -void wxMsgCatalogFile::FillHash(wxMessagesHash& hash, bool convertEncoding) const +void wxMsgCatalogFile::FillHash(wxMessagesHash& hash, + const wxString& msgIdCharset, + bool convertEncoding) const { #if wxUSE_WCHAR_T wxCSConv *csConv = NULL; - if ( !!m_charset ) + if ( !m_charset.IsEmpty() ) csConv = new wxCSConv(m_charset); wxMBConv& inputConv = csConv ? *((wxMBConv*)csConv) : *wxConvCurrent; + + wxCSConv *sourceConv = NULL; + if ( !msgIdCharset.empty() && (m_charset != msgIdCharset) ) + sourceConv = new wxCSConv(msgIdCharset); + #elif wxUSE_FONTMAP + wxASSERT_MSG( msgIdCharset == NULL, + _T("non-ASCII msgid languages only supported if wxUSE_WCHAR_T=1") ); + wxEncodingConverter converter; if ( convertEncoding ) { wxFontEncoding targetEnc = wxFONTENCODING_SYSTEM; - wxFontEncoding enc = wxFontMapper::Get()->CharsetToEncoding(m_charset, FALSE); + wxFontEncoding enc = wxFontMapper::Get()->CharsetToEncoding(m_charset, false); if ( enc == wxFONTENCODING_SYSTEM ) { - convertEncoding = FALSE; // unknown encoding + convertEncoding = false; // unknown encoding } else { @@ -1240,10 +1252,10 @@ 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; + convertEncoding = false; targetEnc = a[0]; } } @@ -1259,11 +1271,17 @@ void wxMsgCatalogFile::FillHash(wxMessagesHash& hash, bool convertEncoding) cons for (size_t i = 0; i < m_numStrings; i++) { const char *data = StringAtOfs(m_pOrigTable, i); -#if wxUSE_WCHAR_T +#if wxUSE_UNICODE wxString msgid(data, inputConv); #else - wxString msgid(data); + wxString msgid; +#if wxUSE_WCHAR_T + if ( convertEncoding && sourceConv ) + msgid = wxString(inputConv.cMB2WC(data), *sourceConv); + else #endif + msgid = data; +#endif // wxUSE_UNICODE data = StringAtOfs(m_pTransTable, i); size_t length = Swap(m_pTransTable[i].nLen); @@ -1300,6 +1318,7 @@ void wxMsgCatalogFile::FillHash(wxMessagesHash& hash, bool convertEncoding) cons } #if wxUSE_WCHAR_T + delete sourceConv; delete csConv; #endif } @@ -1310,7 +1329,7 @@ void wxMsgCatalogFile::FillHash(wxMessagesHash& hash, bool convertEncoding) cons // ---------------------------------------------------------------------------- bool wxMsgCatalog::Load(const wxChar *szDirPrefix, const wxChar *szName, - bool bConvertEncoding) + const wxChar *msgIdCharset, bool bConvertEncoding) { wxMsgCatalogFile file; @@ -1318,11 +1337,11 @@ bool wxMsgCatalog::Load(const wxChar *szDirPrefix, const wxChar *szName, if ( file.Load(szDirPrefix, szName, m_pluralFormsCalculator) ) { - file.FillHash(m_messages, bConvertEncoding); - return TRUE; + file.FillHash(m_messages, msgIdCharset, bConvertEncoding); + return true; } - return FALSE; + return false; } const wxChar *wxMsgCatalog::GetString(const wxChar *sz, size_t n) const @@ -1406,7 +1425,7 @@ bool wxLocale::Init(const wxChar *szName, // the argument to setlocale() szLocale = szShort; - wxCHECK_MSG( szLocale, FALSE, _T("no locale to set in wxLocale::Init()") ); + wxCHECK_MSG( szLocale, false, _T("no locale to set in wxLocale::Init()") ); } #ifdef __WXWINCE__ @@ -1452,7 +1471,7 @@ bool wxLocale::Init(const wxChar *szName, // load the default catalog with wxWidgets standard messages m_pMsgCat = NULL; - bool bOk = TRUE; + bool bOk = true; if ( bLoadDefault ) bOk = AddCatalog(wxT("wxstd")); @@ -1466,24 +1485,24 @@ static wxWCharBuffer wxSetlocaleTryUTF(int c, const wxChar *lc) wxMB2WXbuf l = wxSetlocale(c, lc); if ( !l && lc && lc[0] != 0 ) { - wxString buf(lc); + wxString buf(lc); wxString buf2; - buf2 = buf + wxT(".UTF-8"); - l = wxSetlocale(c, buf2.c_str()); + buf2 = buf + wxT(".UTF-8"); + l = wxSetlocale(c, buf2.c_str()); if ( !l ) { buf2 = buf + wxT(".utf-8"); - l = wxSetlocale(c, buf2.c_str()); + l = wxSetlocale(c, buf2.c_str()); } if ( !l ) { buf2 = buf + wxT(".UTF8"); - l = wxSetlocale(c, buf2.c_str()); + l = wxSetlocale(c, buf2.c_str()); } if ( !l ) { buf2 = buf + wxT(".utf8"); - l = wxSetlocale(c, buf2.c_str()); + l = wxSetlocale(c, buf2.c_str()); } } return l; @@ -1504,7 +1523,7 @@ bool wxLocale::Init(int language, int flags) // We failed to detect system language, so we will use English: if (lang == wxLANGUAGE_UNKNOWN) { - return FALSE; + return false; } const wxLanguageInfo *info = GetLanguageInfo(lang); @@ -1513,7 +1532,7 @@ bool wxLocale::Init(int language, int flags) if (info == NULL) { wxLogError(wxT("Unknown language %i."), lang); - return FALSE; + return false; } wxString name = info->Description; @@ -1561,7 +1580,7 @@ bool wxLocale::Init(int language, int flags) if ( !retloc ) { wxLogError(wxT("Cannot set locale to '%s'."), locale.c_str()); - return FALSE; + return false; } #elif defined(__WIN32__) @@ -1618,7 +1637,7 @@ bool wxLocale::Init(int language, int flags) { wxLogLastError(wxT("SetThreadLocale")); wxLogError(wxT("Cannot set locale to language %s."), name.c_str()); - return FALSE; + return false; } else { @@ -1660,12 +1679,12 @@ bool wxLocale::Init(int language, int flags) if ( !retloc ) { wxLogError(wxT("Cannot set locale to language %s."), name.c_str()); - return FALSE; + return false; } #elif defined(__WXMAC__) || defined(__WXPM__) wxMB2WXbuf retloc = wxSetlocale(LC_ALL , wxEmptyString); #else - return FALSE; + return false; #define WX_NO_LOCALE_SUPPORT #endif @@ -2151,7 +2170,7 @@ void wxLocale::AddCatalogLookupPathPrefix(const wxString& prefix) // 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 +// reflects the way different systems provide the encoding info /* static */ wxString wxLocale::GetSystemEncodingName() @@ -2183,8 +2202,18 @@ wxString wxLocale::GetSystemEncodingName() // 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 ) + // + // 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"); } @@ -2256,11 +2285,11 @@ wxFontEncoding wxLocale::GetSystemEncoding() return wxFONTENCODING_CP950; } #elif defined(__WXMAC__) - TextEncoding encoding = 0 ; + TextEncoding encoding = 0 ; #if TARGET_CARBON - encoding = CFStringGetSystemEncoding() ; + encoding = CFStringGetSystemEncoding() ; #else - UpgradeScriptInfoToTextEncoding ( smSystemScript , kTextLanguageDontCare , kTextRegionDontCare , NULL , &encoding ) ; + UpgradeScriptInfoToTextEncoding ( smSystemScript , kTextLanguageDontCare , kTextRegionDontCare , NULL , &encoding ) ; #endif return wxMacGetFontEncFromSystemEnc( encoding ) ; #elif defined(__UNIX_LIKE__) && wxUSE_FONTMAP @@ -2268,7 +2297,7 @@ wxFontEncoding wxLocale::GetSystemEncoding() if ( !encname.empty() ) { wxFontEncoding enc = wxFontMapper::Get()-> - CharsetToEncoding(encname, FALSE /* not interactive */); + 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 @@ -2310,6 +2339,11 @@ const wxLanguageInfo *wxLocale::GetLanguageInfo(int lang) { CreateLanguagesDB(); + // calling GetLanguageInfo(wxLANGUAGE_DEFAULT) is a natural thing to do, so + // make it work + if ( lang == wxLANGUAGE_DEFAULT ) + lang = GetSystemLanguage(); + const size_t count = ms_languagesDB->GetCount(); for ( size_t i = 0; i < count; i++ ) { @@ -2468,6 +2502,58 @@ const wxChar *wxLocale::GetString(const wxChar *szOrigString, return pszTrans; } +wxString wxLocale::GetHeaderValue( const wxChar* szHeader, + const wxChar* szDomain ) const +{ + if ( wxIsEmpty(szHeader) ) + return wxEmptyString; + + wxChar const * pszTrans = NULL; + wxMsgCatalog *pMsgCat; + + if ( szDomain != NULL ) + { + pMsgCat = FindCatalog(szDomain); + + // does the catalog exist? + if ( pMsgCat == NULL ) + return wxEmptyString; + + pszTrans = pMsgCat->GetString(wxT(""), (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); + if ( pszTrans != NULL ) // take the first found + break; + } + } + + if ( wxIsEmpty(pszTrans) ) + return wxEmptyString; + + wxChar const * pszFound = wxStrstr(pszTrans, szHeader); + if ( pszFound == NULL ) + return wxEmptyString; + + pszFound += wxStrlen(szHeader) + 2 /* ': ' */; + + // Every header is separated by \n + + wxChar const * pszEndLine = wxStrchr(pszFound, wxT('\n')); + if ( pszEndLine == NULL ) pszEndLine = pszFound + wxStrlen(pszFound); + + + // wxString( wxChar*, length); + wxString retVal( pszFound, pszEndLine - pszFound ); + + return retVal; +} + + // find catalog by name in a linked list, return NULL if !found wxMsgCatalog *wxLocale::FindCatalog(const wxChar *szDomain) const { @@ -2490,27 +2576,47 @@ bool wxLocale::IsLoaded(const wxChar *szDomain) const // add a catalog to our linked list bool wxLocale::AddCatalog(const wxChar *szDomain) +{ + return AddCatalog(szDomain, wxLANGUAGE_ENGLISH, NULL); +} + +// add a catalog to our linked list +bool wxLocale::AddCatalog(const wxChar *szDomain, + wxLanguage msgIdLanguage, + const wxChar *msgIdCharset) + { wxMsgCatalog *pMsgCat = new wxMsgCatalog; - if ( pMsgCat->Load(m_strShort, szDomain, m_bConvertEncoding) ) { + if ( pMsgCat->Load(m_strShort, szDomain, msgIdCharset, m_bConvertEncoding) ) { // add it to the head of the list so that in GetString it will // be searched before the catalogs added earlier pMsgCat->m_pNext = m_pMsgCat; m_pMsgCat = pMsgCat; - return TRUE; + return true; } else { // don't add it because it couldn't be loaded anyway delete pMsgCat; - // it's OK to not load English catalog, the texts are embedded in - // the program: - if (m_strShort.Mid(0, 2) == wxT("en")) - return TRUE; + // It is OK to not load catalog if the msgid language and m_language match, + // in which case we can directly display the texts embedded in program's + // source code: + if (m_language == msgIdLanguage) + return true; + + // If there's no exact match, we may still get partial match where the + // (basic) language is same, but the country differs. For example, it's + // permitted to use en_US strings from sources even if m_language is en_GB: + const wxLanguageInfo *msgIdLangInfo = GetLanguageInfo(msgIdLanguage); + if ( msgIdLangInfo && + msgIdLangInfo->CanonicalName.Mid(0, 2) == m_strShort.Mid(0, 2) ) + { + return true; + } - return FALSE; + return false; } } @@ -2630,7 +2736,7 @@ class wxLocaleModule: public wxModule DECLARE_DYNAMIC_CLASS(wxLocaleModule) public: wxLocaleModule() {} - bool OnInit() { return TRUE; } + bool OnInit() { return true; } void OnExit() { wxLocale::DestroyLanguagesDB(); } };