intl.cpp
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 2,270 行 · 第 1/5 页
CPP
2,270 行
}
}
#if wxUSE_WCHAR_T
delete sourceConv;
delete csConv;
#endif
}
// ----------------------------------------------------------------------------
// wxMsgCatalog class
// ----------------------------------------------------------------------------
bool wxMsgCatalog::Load(const wxChar *szDirPrefix, const wxChar *szName,
const wxChar *msgIdCharset, bool bConvertEncoding)
{
wxMsgCatalogFile file;
m_name = szName;
if ( file.Load(szDirPrefix, szName, m_pluralFormsCalculator) )
{
file.FillHash(m_messages, msgIdCharset, bConvertEncoding);
return true;
}
return false;
}
const wxChar *wxMsgCatalog::GetString(const wxChar *sz, size_t n) const
{
int index = 0;
if (n != size_t(-1))
{
index = m_pluralFormsCalculator->evaluate(n);
}
wxMessagesHash::const_iterator i;
if (index != 0)
{
i = m_messages.find(wxString(sz) + wxChar(index)); // plural
}
else
{
i = m_messages.find(sz);
}
if ( i != m_messages.end() )
{
return i->second.c_str();
}
else
return NULL;
}
// ----------------------------------------------------------------------------
// wxLocale
// ----------------------------------------------------------------------------
#include "wx/arrimpl.cpp"
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;
}
void wxLocale::DoCommonInit()
{
m_pszOldLocale = NULL;
m_pOldLocale = wxSetLocale(this);
m_pMsgCat = NULL;
m_language = wxLANGUAGE_UNKNOWN;
m_initialized = false;
}
// NB: this function has (desired) side effect of changing current locale
bool wxLocale::Init(const wxChar *szName,
const wxChar *szShort,
const wxChar *szLocale,
bool bLoadDefault,
bool bConvertEncoding)
{
wxASSERT_MSG( !m_initialized,
_T("you can't call wxLocale::Init more than once") );
m_initialized = true;
m_strLocale = szName;
m_strShort = szShort;
m_bConvertEncoding = bConvertEncoding;
m_language = wxLANGUAGE_UNKNOWN;
// change current locale (default: same as long name)
if ( szLocale == NULL )
{
// the argument to setlocale()
szLocale = szShort;
wxCHECK_MSG( szLocale, false, _T("no locale to set in wxLocale::Init()") );
}
#ifdef __WXWINCE__
// FIXME: I'm guessing here
wxChar localeName[256];
int ret = GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SLANGUAGE, localeName,
256);
if (ret != 0)
{
m_pszOldLocale = wxStrdup(localeName);
}
else
m_pszOldLocale = NULL;
// TODO: how to find languageId
// SetLocaleInfo(languageId, SORT_DEFAULT, localeName);
#else
wxMB2WXbuf oldLocale = wxSetlocale(LC_ALL, szLocale);
if ( oldLocale )
m_pszOldLocale = wxStrdup(oldLocale);
else
m_pszOldLocale = NULL;
#endif
if ( m_pszOldLocale == NULL )
wxLogError(_("locale '%s' can not be set."), szLocale);
// the short name will be used to look for catalog files as well,
// so we need something here
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] )
{
m_strShort += (wxChar)wxTolower(szLocale[0]);
if ( szLocale[1] )
m_strShort += (wxChar)wxTolower(szLocale[1]);
}
}
// 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;
}
#if defined(__UNIX__) && wxUSE_UNICODE && !defined(__WXMAC__)
static wxWCharBuffer wxSetlocaleTryUTF(int c, const wxChar *lc)
{
wxMB2WXbuf l = wxSetlocale(c, lc);
if ( !l && lc && lc[0] != 0 )
{
wxString buf(lc);
wxString buf2;
buf2 = buf + wxT(".UTF-8");
l = wxSetlocale(c, buf2.c_str());
if ( !l )
{
buf2 = buf + wxT(".utf-8");
l = wxSetlocale(c, buf2.c_str());
}
if ( !l )
{
buf2 = buf + wxT(".UTF8");
l = wxSetlocale(c, buf2.c_str());
}
if ( !l )
{
buf2 = buf + wxT(".utf8");
l = wxSetlocale(c, buf2.c_str());
}
}
return l;
}
#else
#define wxSetlocaleTryUTF(c, lc) wxSetlocale(c, lc)
#endif
bool wxLocale::Init(int language, int flags)
{
int lang = language;
if (lang == wxLANGUAGE_DEFAULT)
{
// auto detect the language
lang = GetSystemLanguage();
}
// We failed to detect system language, so we will use English:
if (lang == wxLANGUAGE_UNKNOWN)
{
return false;
}
const wxLanguageInfo *info = GetLanguageInfo(lang);
// Unknown language:
if (info == NULL)
{
wxLogError(wxT("Unknown language %i."), lang);
return false;
}
wxString name = info->Description;
wxString canonical = info->CanonicalName;
wxString locale;
// Set the locale:
#if defined(__UNIX__) && !defined(__WXMAC__)
if (language == wxLANGUAGE_DEFAULT)
locale = wxEmptyString;
else
locale = info->CanonicalName;
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
retloc = wxSetlocaleTryUTF(LC_ALL, locale.Mid(0,2));
}
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);
}
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));
}
if ( !retloc )
{
wxLogError(wxT("Cannot set locale to '%s'."), locale.c_str());
return false;
}
#elif defined(__WIN32__)
#if wxUSE_UNICODE && (defined(__VISUALC__) || defined(__MINGW32__))
// NB: setlocale() from msvcrt.dll (used by VC++ and Mingw)
// can't set locale to language that can only be written using
// Unicode. Therefore wxSetlocale call failed, but we don't want
// to report it as an error -- so that at least message catalogs
// can be used. Watch for code marked with
// #ifdef SETLOCALE_FAILS_ON_UNICODE_LANGS bellow.
#define SETLOCALE_FAILS_ON_UNICODE_LANGS
#endif
#if !wxUSE_UNICODE
const
#endif
wxMB2WXbuf retloc = wxT("C");
if (language != wxLANGUAGE_DEFAULT)
{
if (info->WinLang == 0)
{
wxLogWarning(wxT("Locale '%s' not supported by OS."), name.c_str());
// retloc already set to "C"
}
else
{
int codepage
#ifdef SETLOCALE_FAILS_ON_UNICODE_LANGS
= -1
#endif
;
wxUint32 lcid = MAKELCID(MAKELANGID(info->WinLang, info->WinSublang),
SORT_DEFAULT);
// FIXME
#ifndef __WXWINCE__
SetThreadLocale(lcid);
#endif
// NB: we must translate LCID to CRT's setlocale string ourselves,
// because SetThreadLocale does not modify change the
// interpretation of setlocale(LC_ALL, "") call:
wxChar buffer[256];
buffer[0] = wxT('\0');
GetLocaleInfo(lcid, LOCALE_SENGLANGUAGE, buffer, 256);
locale << buffer;
if (GetLocaleInfo(lcid, LOCALE_SENGCOUNTRY, buffer, 256) > 0)
locale << wxT("_") << buffer;
if (GetLocaleInfo(lcid, LOCALE_IDEFAULTANSICODEPAGE, buffer, 256) > 0)
{
codepage = wxAtoi(buffer);
if (codepage != 0)
locale << wxT(".") << buffer;
}
if (locale.empty())
{
wxLogLastError(wxT("SetThreadLocale"));
wxLogError(wxT("Cannot set locale to language %s."), name.c_str());
return false;
}
else
{
// FIXME
#ifndef __WXWINCE__
retloc = wxSetlocale(LC_ALL, locale);
#endif
#ifdef SETLOCALE_FAILS_ON_UNICODE_LANGS
if (codepage == 0 && (const wxChar*)retloc == NULL)
{
retloc = wxT("C");
}
#endif
}
}
}
else
{
// FIXME
#ifndef __WXWINCE__
retloc = wxSetlocale(LC_ALL, wxEmptyString);
#else
retloc = NULL;
#endif
#ifdef SETLOCALE_FAILS_ON_UNICODE_LANGS
if ((const wxChar*)retloc == NULL)
{
wxChar buffer[16];
if (GetLocaleInfo(LOCALE_USER_DEFAULT,
LOCALE_IDEFAULTANSICODEPAGE, buffer, 16) > 0 &&
wxStrcmp(buffer, wxT("0")) == 0)
{
retloc = wxT("C");
}
}
#endif
}
if ( !retloc )
{
wxLogError(wxT("Cannot set locale to language %s."), name.c_str());
return false;
}
#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;
}
#elif defined(__WXPM__)
wxMB2WXbuf retloc = wxSetlocale(LC_ALL , wxEmptyString);
#else
return false;
#define WX_NO_LOCALE_SUPPORT
#endif
#ifndef WX_NO_LOCALE_SUPPORT
wxChar *szLocale = retloc ? wxStrdup(retloc) : NULL;
bool ret = Init(name, canonical, szLocale,
(flags & wxLOCALE_LOAD_DEFAULT) != 0,
(flags & wxLOCALE_CONV_ENCODING) != 0);
free(szLocale);
if (IsOk()) // setlocale() succeeded
m_language = lang;
return ret;
#endif
}
void wxLocale::AddCatalogLookupPathPrefix(const wxString& prefix)
{
if ( s_searchPrefixes.Index(prefix) == wxNOT_FOUND )
{
s_searchPrefixes.Add(prefix);
}
//else: already have it
}
/*static*/ int wxLocale::GetSystemLanguage()
{
CreateLanguagesDB();
// init i to avoid compiler warning
size_t i = 0,
count = ms_languagesDB->GetCount();
#if defined(__UNIX__) && !defined(__WXMAC__)
// first get the string identifying the language from the environment
wxString langFull;
if (!wxGetEnv(wxT("LC_ALL"), &langFull) &&
!wxGetEnv(wxT("LC_MESSAGES"), &langFull) &&
!wxGetEnv(wxT("LANG"), &langFull))
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?