// 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:
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
// ----------------------------------------------------------------------------
wxPluralFormsNodePtr m_plural;
};
-wxDEFINE_SCOPED_PTR_TYPE(wxPluralFormsCalculator);
+wxDEFINE_SCOPED_PTR_TYPE(wxPluralFormsCalculator)
void wxPluralFormsCalculator::init(wxPluralFormsToken::Number nplurals,
wxPluralFormsNode* plural)
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 )
{
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(_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() )
return false;
// get the file size (assume it is less than 4Gb...)
- wxFileOffset 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, (size_t)nSize) != nSize ) {
+ if ( fileMsg.Read(m_pData, nSize) != lenFile ) {
wxDELETEA(m_pData);
return false;
}
}
else
{
- wxLogVerbose(_("Cannot parse Plural-Forms:'%s'"),
- pfs.c_str());
+ wxLogVerbose(_("Cannot parse Plural-Forms:'%s'"), pfs.c_str());
}
}
}
if ( convertEncoding )
{
if ( m_charset.empty() )
+ {
inputConv = wxConvCurrent;
+ }
else
+ {
inputConv =
csConv = new wxCSConv(m_charset);
+ }
}
- else // no conversion needed
+ 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
}
// conversion to apply to msgid strings before looking them up: we only
#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 // ASCII
wxString msgid;
-#if wxUSE_WCHAR_T
- if ( inputConv && 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
#include "wx/arrimpl.cpp"
WX_DECLARE_EXPORTED_OBJARRAY(wxLanguageInfo, wxLanguageInfoArray);
-WX_DEFINE_OBJARRAY(wxLanguageInfoArray);
+WX_DEFINE_OBJARRAY(wxLanguageInfoArray)
wxLanguageInfoArray *wxLocale::ms_languagesDB = NULL;
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__))
wxLogError(wxT("Cannot set locale to '%s'."), locale.c_str());
return false;
}
-#elif defined(__WXPM__)
- wxMB2WXbuf retloc = wxSetlocale(LC_ALL , wxEmptyString);
#else
return false;
#define WX_NO_LOCALE_SUPPORT
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
#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...
}
#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;
}
{
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__
LNG(wxLANGUAGE_ZHUANG, "za" , 0 , 0 , "Zhuang")
LNG(wxLANGUAGE_ZULU, "zu" , 0 , 0 , "Zulu")
-};
+}
#undef LNG
// --- --- --- generated code ends here --- --- ---
#endif // wxUSE_INTL
-