#include "wx/hashset.h"
#include "wx/filesys.h"
-#if defined(__WXMAC__)
- #include "wx/mac/private.h" // includes mac headers
-#endif
-
#if defined(__DARWIN__)
- #include "wx/mac/corefoundation/cfref.h"
+ #include "wx/osx/core/cfref.h"
#include <CoreFoundation/CFLocale.h>
- #include "wx/mac/corefoundation/cfstring.h"
+ #include "wx/osx/core/cfstring.h"
#endif
// ----------------------------------------------------------------------------
const size_t32 MSGCATALOG_MAGIC = 0x950412de;
const size_t32 MSGCATALOG_MAGIC_SW = 0xde120495;
-// the constants describing the format of lang_LANG locale string
+// the constants describing the format of ll_CC 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 '_'
static wxLocale *wxSetLocale(wxLocale *pLocale);
-// helper functions of GetSystemLanguage()
-#ifdef __UNIX__
+namespace
+{
// get just the language part
-static inline wxString ExtractLang(const wxString& langFull)
+inline wxString ExtractLang(const wxString& langFull)
{
return langFull.Left(LEN_LANG);
}
+// helper functions of GetSystemLanguage()
+#ifdef __UNIX__
+
// get everything else (including the leading '_')
-static inline wxString ExtractNotLang(const wxString& langFull)
+inline wxString ExtractNotLang(const wxString& langFull)
{
return langFull.Mid(LEN_LANG);
}
#endif // __UNIX__
+} // anonymous namespace
// ----------------------------------------------------------------------------
// Plural forms parser
bool wxPluralFormsScanner::nextToken()
{
wxPluralFormsToken::Type type = wxPluralFormsToken::T_ERROR;
- while (isspace(*m_s))
+ while (isspace((unsigned char) *m_s))
{
++m_s;
}
{
type = wxPluralFormsToken::T_EOF;
}
- else if (isdigit(*m_s))
+ else if (isdigit((unsigned char) *m_s))
{
wxPluralFormsToken::Number number = *m_s++ - '0';
- while (isdigit(*m_s))
+ while (isdigit((unsigned char) *m_s))
{
number = number * 10 + (*m_s++ - '0');
}
m_token.setNumber(number);
type = wxPluralFormsToken::T_NUMBER;
}
- else if (isalpha(*m_s))
+ else if (isalpha((unsigned char) *m_s))
{
const char* begin = m_s++;
- while (isalnum(*m_s))
+ while (isalnum((unsigned char) *m_s))
{
++m_s;
}
// facilitate doing pointer arithmetic with it
char *StringData() const
{
- return wx_static_cast(char *, m_data.GetData());
+ return static_cast<char *>(m_data.GetData());
}
const char *StringAtOfs(wxMsgTableEntry *pTable, size_t32 n) const
#ifdef __WXMSW__
+// helper used by wxLanguageInfo::GetLocaleName() and elsewhere to determine
+// whether the locale is Unicode-only (it is if this function returns empty
+// string)
+static wxString wxGetANSICodePageForLocale(LCID lcid)
+{
+ wxString cp;
+
+ wxChar buffer[16];
+ if ( ::GetLocaleInfo(lcid, LOCALE_IDEFAULTANSICODEPAGE,
+ buffer, WXSIZEOF(buffer)) > 0 )
+ {
+ if ( buffer[0] != _T('0') || buffer[1] != _T('\0') )
+ cp = buffer;
+ //else: this locale doesn't use ANSI code page
+ }
+
+ return cp;
+}
+
wxUint32 wxLanguageInfo::GetLCID() const
{
return MAKELCID(MAKELANGID(WinLang, WinSublang), SORT_DEFAULT);
locale << _T('_') << buffer;
}
- if ( ::GetLocaleInfo(lcid, LOCALE_IDEFAULTANSICODEPAGE,
- buffer, WXSIZEOF(buffer)) > 0 )
+ const wxString cp = wxGetANSICodePageForLocale(lcid);
+ if ( !cp.empty() )
{
- if ( buffer[0] != _T('0') || buffer[1] != _T('\0') )
- locale << _T('.') << buffer;
- //else: this locale doesn't use ANSI code page
+ locale << _T('.') << cp;
}
return locale;
bool wxMsgCatalogFile::Load(const wxString& szDirPrefix, const wxString& szName,
wxPluralFormsCalculatorPtr& rPluralFormsCalculator)
{
+ wxCHECK_MSG( szDirPrefix.length() >= LEN_LANG, false,
+ "invalid language specification" );
+
wxString searchPath;
#if wxUSE_FONTMAP
searchPath += GetFullSearchPath(szDirPrefix);
- size_t sublocaleIndex = szDirPrefix.find(wxS('_'));
- if ( sublocaleIndex != wxString::npos )
+ if ( szDirPrefix[LEN_LANG] == wxS('_') )
{
- // also add just base locale name: for things like "fr_BE" (belgium
- // french) we should use "fr" if no belgium specific message catalogs
- // exist
+ // also add just base locale name: for things like "fr_BE" (Belgium
+ // French) we should use fall back on plain "fr" if no Belgium-specific
+ // message catalogs exist
searchPath << wxPATH_SEP
- << GetFullSearchPath(szDirPrefix.Left(sublocaleIndex));
+ << GetFullSearchPath(ExtractLang(szDirPrefix));
}
// don't give translation errors here because the wxstd catalog might
// read the whole file in memory
if ( fileMsg.Read(m_data.GetWriteBuf(nSize), nSize) != lenFile )
return false;
+
+ m_data.UngetWriteBuf(nSize);
#endif // wxUSE_FILESYSTEM/!wxUSE_FILESYSTEM
wxS("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(wxConvLibc.cWC2MB(localeName));
- }
- else
- m_pszOldLocale = NULL;
-
- // TODO: how to find languageId
- // SetLocaleInfo(languageId, SORT_DEFAULT, localeName);
-#else
const char *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);
const char *retloc = wxSetlocaleTryUTF8(LC_ALL, locale);
- const wxString langOnly = locale.Left(2);
+ const wxString langOnly = ExtractLang(locale);
if ( !retloc )
{
// Some C libraries don't like xx_YY form and require xx only
// so will translate the abbrev for them
wxString localeAlt;
if ( langOnly == wxS("he") )
- localeAlt = wxS("iw") + locale.Mid(3);
+ localeAlt = wxS("iw") + ExtractNotLang(locale);
else if ( langOnly == wxS("id") )
- localeAlt = wxS("in") + locale.Mid(3);
+ localeAlt = wxS("in") + ExtractNotLang(locale);
else if ( langOnly == wxS("yi") )
- localeAlt = wxS("ji") + locale.Mid(3);
+ localeAlt = wxS("ji") + ExtractNotLang(locale);
else if ( langOnly == wxS("nb") )
localeAlt = wxS("no_NO");
else if ( langOnly == wxS("nn") )
{
retloc = wxSetlocaleTryUTF8(LC_ALL, localeAlt);
if ( !retloc )
- retloc = wxSetlocaleTryUTF8(LC_ALL, localeAlt.Left(2));
+ retloc = wxSetlocaleTryUTF8(LC_ALL, ExtractLang(localeAlt));
}
}
#endif // __AIX__
#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 below.
- #define SETLOCALE_FAILS_ON_UNICODE_LANGS
- #endif
-
const char *retloc = "C";
- if (language != wxLANGUAGE_DEFAULT)
+ if ( language != wxLANGUAGE_DEFAULT )
{
- if (info->WinLang == 0)
+ if ( info->WinLang == 0 )
{
wxLogWarning(wxS("Locale '%s' not supported by OS."), name.c_str());
// retloc already set to "C"
}
- else
+ else // language supported by Windows
{
+ // Windows CE doesn't have SetThreadLocale() and there doesn't seem
+ // to be any equivalent
+#ifndef __WXWINCE__
const wxUint32 lcid = info->GetLCID();
- // FIXME
-#ifndef __WXWINCE__
// change locale used by Windows functions
::SetThreadLocale(lcid);
#endif
+
// and also call setlocale() to change locale used by the CRT
locale = info->GetLocaleName();
if ( locale.empty() )
}
else // have a valid locale
{
- // FIXME
-#ifndef __WXWINCE__
retloc = wxSetlocale(LC_ALL, locale);
-#endif
-#ifdef SETLOCALE_FAILS_ON_UNICODE_LANGS
- if ( !retloc )
- {
- // GetLocaleName() returns a string without period only if
- // there is no associated ANSI code page
- if ( locale.find(_T('.')) == wxString::npos )
- {
- retloc = "C";
- }
- //else: locale has code page information and hence this is
- // a real error
- }
-#endif // SETLOCALE_FAILS_ON_UNICODE_LANGS
}
}
}
- else
+ else // language == wxLANGUAGE_DEFAULT
{
- // FIXME
-#ifndef __WXWINCE__
retloc = wxSetlocale(LC_ALL, wxEmptyString);
-#else
- retloc = NULL;
-#endif
-#ifdef SETLOCALE_FAILS_ON_UNICODE_LANGS
- if (retloc == NULL)
+ }
+
+#if wxUSE_UNICODE && (defined(__VISUALC__) || defined(__MINGW32__))
+ // VC++ setlocale() (also used by Mingw) can't set locale to languages that
+ // can only be written using Unicode, therefore wxSetlocale() call fails
+ // for such languages but we don't want to report it as an error -- so that
+ // at least message catalogs can be used.
+ if ( !retloc )
+ {
+ if ( wxGetANSICodePageForLocale(LOCALE_USER_DEFAULT).empty() )
{
- wxChar buffer[16];
- if (GetLocaleInfo(LOCALE_USER_DEFAULT,
- LOCALE_IDEFAULTANSICODEPAGE, buffer, 16) > 0 &&
- wxStrcmp(buffer, wxS("0")) == 0)
- {
- retloc = "C";
- }
+ // we set the locale to a Unicode-only language, don't treat the
+ // inability of CRT to use it as an error
+ retloc = "C";
}
-#endif
}
+#endif // CRT not handling Unicode-only languages
if ( !retloc )
ret = false;
if ( !retloc )
{
// Some C libraries don't like xx_YY form and require xx only
- retloc = wxSetlocale(LC_ALL, locale.Mid(0,2));
+ retloc = wxSetlocale(LC_ALL, ExtractLang(locale));
}
#else
wxUnusedVar(flags);
// for now we don't use the encoding, although we probably should (doing
// translations of the msg catalogs on the fly as required) (TODO)
//
- // we don't use the modifiers neither but we probably should translate
- // "euro" into iso885915
+ // we need the modified for languages like Valencian: ca_ES@valencia
+ // though, remember it
+ wxString modifier;
+ size_t posModifier = langFull.find_first_of(wxS("@"));
+ if ( posModifier != wxString::npos )
+ modifier = langFull.Mid(posModifier);
+
size_t posEndLang = langFull.find_first_of(wxS("@."));
if ( posEndLang != wxString::npos )
{
}
// 1. Try to find the language either as is:
- for ( i = 0; i < count; i++ )
+ // a) With modifier if set
+ if ( !modifier.empty() )
+ {
+ wxString langFullWithModifier = langFull + modifier;
+ for ( i = 0; i < count; i++ )
+ {
+ if ( ms_languagesDB->Item(i).CanonicalName == langFullWithModifier )
+ break;
+ }
+ }
+
+ // b) Without modifier
+ if ( modifier.empty() || i == count )
{
- if ( ms_languagesDB->Item(i).CanonicalName == langFull )
+ for ( i = 0; i < count; i++ )
{
- break;
+ if ( ms_languagesDB->Item(i).CanonicalName == langFull )
+ break;
}
}
return wxFONTENCODING_CP950;
}
#elif defined(__WXMAC__)
- TextEncoding encoding = 0 ;
+ CFStringEncoding encoding = 0 ;
encoding = CFStringGetSystemEncoding() ;
return wxMacGetFontEncFromSystemEnc( encoding ) ;
#elif defined(__UNIX_LIKE__) && wxUSE_FONTMAP
wxString wxLocale::GetSysName() const
{
- // FIXME
-#ifndef __WXWINCE__
return wxSetlocale(LC_ALL, NULL);
-#else
- return wxEmptyString;
-#endif
}
// clean up
// restore old locale pointer
wxSetLocale(m_pOldLocale);
- // FIXME
-#ifndef __WXWINCE__
wxSetlocale(LC_ALL, m_pszOldLocale);
-#endif
free((wxChar *)m_pszOldLocale); // const_cast
}
if ( !tmp )
{
// Some C libraries don't like xx_YY form and require xx only
- tmp = wxSetlocaleTryUTF8(LC_ALL, info->CanonicalName.Left(2));
+ tmp = wxSetlocaleTryUTF8(LC_ALL, ExtractLang(info->CanonicalName));
if ( !tmp )
return false;
}
const wxString& msgIdCharset)
{
- wxMsgCatalog *pMsgCat = new wxMsgCatalog;
+ wxCHECK_MSG( IsOk(), false, "must initialize catalog first" );
- 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;
- }
- else {
- // don't add it because it couldn't be loaded anyway
- delete pMsgCat;
// 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)
+ if ( msgIdLanguage == m_language )
+ return true;
+
+
+ wxMsgCatalog *pMsgCat = new wxMsgCatalog;
+
+ 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;
+ }
+
+ // don't add it because it couldn't be loaded anyway
+ delete pMsgCat;
+
// 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) )
+ ExtractLang(msgIdLangInfo->CanonicalName) == ExtractLang(m_strShort) )
{
return true;
}
return false;
- }
}
// ----------------------------------------------------------------------------
wxCFRef<CFLocaleRef> userLocaleRef(userLocaleRefRaw);
- CFTypeRef cfstr;
+ CFStringRef cfstr = 0;
switch ( index )
{
case wxLOCALE_THOUSANDS_SEP:
- cfstr = CFLocaleGetValue(userLocaleRef, kCFLocaleGroupingSeparator);
+ cfstr = (CFStringRef) CFLocaleGetValue(userLocaleRef, kCFLocaleGroupingSeparator);
break;
case wxLOCALE_DECIMAL_POINT:
- cfstr = CFLocaleGetValue(userLocaleRef, kCFLocaleDecimalSeparator);
+ cfstr = (CFStringRef) CFLocaleGetValue(userLocaleRef, kCFLocaleDecimalSeparator);
break;
default:
wxFAIL_MSG( "Unknown locale info" );
+ cfstr = CFSTR("");
+ break;
}
- wxCFStringRef
- str(CFStringCreateCopy(NULL, static_cast<CFStringRef>(cfstr)));
+ wxCFStringRef str(wxCFRetain(cfstr));
return str.AsString();
}
#ifndef LANG_RUSSIAN
#define LANG_RUSSIAN (0)
#endif
+#ifndef LANG_SAMI
+#define LANG_SAMI (0)
+#endif
#ifndef LANG_SANSKRIT
#define LANG_SANSKRIT (0)
#endif
LNG(wxLANGUAGE_FRENCH_SWISS, "fr_CH", LANG_FRENCH , SUBLANG_FRENCH_SWISS , wxLayout_LeftToRight, "French (Swiss)")
LNG(wxLANGUAGE_FRISIAN, "fy" , 0 , 0 , wxLayout_LeftToRight, "Frisian")
LNG(wxLANGUAGE_GALICIAN, "gl_ES", 0 , 0 , wxLayout_LeftToRight, "Galician")
- LNG(wxLANGUAGE_GEORGIAN, "ka" , LANG_GEORGIAN , SUBLANG_DEFAULT , wxLayout_LeftToRight, "Georgian")
+ LNG(wxLANGUAGE_GEORGIAN, "ka_GE", LANG_GEORGIAN , SUBLANG_DEFAULT , wxLayout_LeftToRight, "Georgian")
LNG(wxLANGUAGE_GERMAN, "de_DE", LANG_GERMAN , SUBLANG_GERMAN , wxLayout_LeftToRight, "German")
LNG(wxLANGUAGE_GERMAN_AUSTRIAN, "de_AT", LANG_GERMAN , SUBLANG_GERMAN_AUSTRIAN , wxLayout_LeftToRight, "German (Austrian)")
LNG(wxLANGUAGE_GERMAN_BELGIUM, "de_BE", 0 , 0 , wxLayout_LeftToRight, "German (Belgium)")
LNG(wxLANGUAGE_KIRUNDI, "rn" , 0 , 0 , wxLayout_LeftToRight, "Kirundi")
LNG(wxLANGUAGE_KONKANI, "" , LANG_KONKANI , SUBLANG_DEFAULT , wxLayout_LeftToRight, "Konkani")
LNG(wxLANGUAGE_KOREAN, "ko_KR", LANG_KOREAN , SUBLANG_KOREAN , wxLayout_LeftToRight, "Korean")
- LNG(wxLANGUAGE_KURDISH, "ku" , 0 , 0 , wxLayout_LeftToRight, "Kurdish")
+ LNG(wxLANGUAGE_KURDISH, "ku_TR", 0 , 0 , wxLayout_LeftToRight, "Kurdish")
LNG(wxLANGUAGE_LAOTHIAN, "lo" , 0 , 0 , wxLayout_LeftToRight, "Laothian")
LNG(wxLANGUAGE_LATIN, "la" , 0 , 0 , wxLayout_LeftToRight, "Latin")
LNG(wxLANGUAGE_LATVIAN, "lv_LV", LANG_LATVIAN , SUBLANG_DEFAULT , wxLayout_LeftToRight, "Latvian")
LNG(wxLANGUAGE_MOLDAVIAN, "mo" , 0 , 0 , wxLayout_LeftToRight, "Moldavian")
LNG(wxLANGUAGE_MONGOLIAN, "mn" , 0 , 0 , wxLayout_LeftToRight, "Mongolian")
LNG(wxLANGUAGE_NAURU, "na" , 0 , 0 , wxLayout_LeftToRight, "Nauru")
- LNG(wxLANGUAGE_NEPALI, "ne" , LANG_NEPALI , SUBLANG_DEFAULT , wxLayout_LeftToRight, "Nepali")
+ LNG(wxLANGUAGE_NEPALI, "ne_NP", LANG_NEPALI , SUBLANG_DEFAULT , wxLayout_LeftToRight, "Nepali")
LNG(wxLANGUAGE_NEPALI_INDIA, "ne_IN", LANG_NEPALI , SUBLANG_NEPALI_INDIA , wxLayout_LeftToRight, "Nepali (India)")
LNG(wxLANGUAGE_NORWEGIAN_BOKMAL, "nb_NO", LANG_NORWEGIAN , SUBLANG_NORWEGIAN_BOKMAL , wxLayout_LeftToRight, "Norwegian (Bokmal)")
LNG(wxLANGUAGE_NORWEGIAN_NYNORSK, "nn_NO", LANG_NORWEGIAN , SUBLANG_NORWEGIAN_NYNORSK , wxLayout_LeftToRight, "Norwegian (Nynorsk)")
LNG(wxLANGUAGE_ROMANIAN, "ro_RO", LANG_ROMANIAN , SUBLANG_DEFAULT , wxLayout_LeftToRight, "Romanian")
LNG(wxLANGUAGE_RUSSIAN, "ru_RU", LANG_RUSSIAN , SUBLANG_DEFAULT , wxLayout_LeftToRight, "Russian")
LNG(wxLANGUAGE_RUSSIAN_UKRAINE, "ru_UA", 0 , 0 , wxLayout_LeftToRight, "Russian (Ukraine)")
+ LNG(wxLANGUAGE_SAMI, "se_NO", LANG_SAMI , SUBLANG_DEFAULT , wxLayout_LeftToRight, "Northern Sami")
LNG(wxLANGUAGE_SAMOAN, "sm" , 0 , 0 , wxLayout_LeftToRight, "Samoan")
LNG(wxLANGUAGE_SANGHO, "sg" , 0 , 0 , wxLayout_LeftToRight, "Sangho")
LNG(wxLANGUAGE_SANSKRIT, "sa" , LANG_SANSKRIT , SUBLANG_DEFAULT , wxLayout_LeftToRight, "Sanskrit")
LNG(wxLANGUAGE_SCOTS_GAELIC, "gd" , 0 , 0 , wxLayout_LeftToRight, "Scots Gaelic")
+ LNG(wxLANGUAGE_SERBIAN, "sr_SR", LANG_SERBIAN , SUBLANG_DEFAULT , wxLayout_LeftToRight, "Serbian")
+ LNG(wxLANGUAGE_SERBIAN_CYRILLIC, "sr_SR", LANG_SERBIAN , SUBLANG_SERBIAN_CYRILLIC , wxLayout_LeftToRight, "Serbian (Cyrillic)")
+ LNG(wxLANGUAGE_SERBIAN_LATIN, "sr_SR@latin", LANG_SERBIAN , SUBLANG_SERBIAN_LATIN , wxLayout_LeftToRight, "Serbian (Latin)")
LNG(wxLANGUAGE_SERBIAN_CYRILLIC, "sr_YU", LANG_SERBIAN , SUBLANG_SERBIAN_CYRILLIC , wxLayout_LeftToRight, "Serbian (Cyrillic)")
- LNG(wxLANGUAGE_SERBIAN_LATIN, "sr_YU", LANG_SERBIAN , SUBLANG_SERBIAN_LATIN , wxLayout_LeftToRight, "Serbian (Latin)")
+ LNG(wxLANGUAGE_SERBIAN_LATIN, "sr_YU@latin", LANG_SERBIAN , SUBLANG_SERBIAN_LATIN , wxLayout_LeftToRight, "Serbian (Latin)")
LNG(wxLANGUAGE_SERBO_CROATIAN, "sh" , 0 , 0 , wxLayout_LeftToRight, "Serbo-Croatian")
LNG(wxLANGUAGE_SESOTHO, "st" , 0 , 0 , wxLayout_LeftToRight, "Sesotho")
LNG(wxLANGUAGE_SETSWANA, "tn" , 0 , 0 , wxLayout_LeftToRight, "Setswana")
LNG(wxLANGUAGE_UZBEK, "uz" , LANG_UZBEK , SUBLANG_DEFAULT , wxLayout_LeftToRight, "Uzbek")
LNG(wxLANGUAGE_UZBEK_CYRILLIC, "uz" , LANG_UZBEK , SUBLANG_UZBEK_CYRILLIC , wxLayout_LeftToRight, "Uzbek (Cyrillic)")
LNG(wxLANGUAGE_UZBEK_LATIN, "uz" , LANG_UZBEK , SUBLANG_UZBEK_LATIN , wxLayout_LeftToRight, "Uzbek (Latin)")
+ LNG(wxLANGUAGE_VALENCIAN, "ca_ES@valencia", 0 , 0 , wxLayout_LeftToRight, "Valencian (Souternhern Catalan)")
LNG(wxLANGUAGE_VIETNAMESE, "vi_VN", LANG_VIETNAMESE, SUBLANG_DEFAULT , wxLayout_LeftToRight, "Vietnamese")
LNG(wxLANGUAGE_VOLAPUK, "vo" , 0 , 0 , wxLayout_LeftToRight, "Volapuk")
LNG(wxLANGUAGE_WELSH, "cy" , 0 , 0 , wxLayout_LeftToRight, "Welsh")