1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/common/intl.cpp 
   3 // Purpose:     Internationalization and localisation for wxWidgets 
   4 // Author:      Vadim Zeitlin 
   5 // Modified by: Michael N. Filippov <michael@idisys.iae.nsk.su> 
   6 //              (2003/09/30 - PluralForms support) 
   9 // Copyright:   (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr> 
  10 // Licence:     wxWindows licence 
  11 ///////////////////////////////////////////////////////////////////////////// 
  13 // ============================================================================ 
  15 // ============================================================================ 
  17 // ---------------------------------------------------------------------------- 
  19 // ---------------------------------------------------------------------------- 
  22 // The following define is needed by Innotek's libc to 
  23 // make the definition of struct localeconv available. 
  24 #define __INTERNAL_DEFS 
  27 // For compilers that support precompilation, includes "wx.h". 
  28 #include "wx/wxprec.h" 
  37     #include "wx/dynarray.h" 
  38     #include "wx/string.h" 
  43     #include "wx/hashmap.h" 
  44     #include "wx/module.h" 
  54 #ifdef HAVE_LANGINFO_H 
  59     #include "wx/msw/private.h" 
  60 #elif defined(__UNIX_LIKE__) 
  61     #include "wx/fontmap.h"         // for CharsetToEncoding() 
  65 #include "wx/filename.h" 
  66 #include "wx/tokenzr.h" 
  67 #include "wx/fontmap.h" 
  68 #include "wx/encconv.h" 
  69 #include "wx/ptr_scpd.h" 
  70 #include "wx/apptrait.h" 
  71 #include "wx/stdpaths.h" 
  72 #include "wx/hashset.h" 
  74 #if defined(__WXMAC__) 
  75     #include  "wx/mac/private.h"  // includes mac headers 
  78 // ---------------------------------------------------------------------------- 
  80 // ---------------------------------------------------------------------------- 
  82 // this should *not* be wxChar, this type must have exactly 8 bits! 
  83 typedef wxUint8 size_t8
; 
  84 typedef wxUint32 size_t32
; 
  86 // ---------------------------------------------------------------------------- 
  88 // ---------------------------------------------------------------------------- 
  90 // magic number identifying the .mo format file 
  91 const size_t32 MSGCATALOG_MAGIC    
= 0x950412de; 
  92 const size_t32 MSGCATALOG_MAGIC_SW 
= 0xde120495; 
  94 // the constants describing the format of lang_LANG locale string 
  95 static const size_t LEN_LANG 
= 2; 
  96 static const size_t LEN_SUBLANG 
= 2; 
  97 static const size_t LEN_FULL 
= LEN_LANG 
+ 1 + LEN_SUBLANG
; // 1 for '_' 
  99 #define TRACE_I18N _T("i18n") 
 101 // ---------------------------------------------------------------------------- 
 103 // ---------------------------------------------------------------------------- 
 107 // small class to suppress the translation erros until exit from current scope 
 111     NoTransErr() { ms_suppressCount
++; } 
 112    ~NoTransErr() { ms_suppressCount
--;  } 
 114    static bool Suppress() { return ms_suppressCount 
> 0; } 
 117    static size_t ms_suppressCount
; 
 120 size_t NoTransErr::ms_suppressCount 
= 0; 
 131 #endif // Debug/!Debug 
 133 static wxLocale 
*wxSetLocale(wxLocale 
*pLocale
); 
 135 // helper functions of GetSystemLanguage() 
 138 // get just the language part 
 139 static inline wxString 
ExtractLang(const wxString
& langFull
) 
 141     return langFull
.Left(LEN_LANG
); 
 144 // get everything else (including the leading '_') 
 145 static inline wxString 
ExtractNotLang(const wxString
& langFull
) 
 147     return langFull
.Mid(LEN_LANG
); 
 153 // ---------------------------------------------------------------------------- 
 154 // Plural forms parser 
 155 // ---------------------------------------------------------------------------- 
 161     LogicalOrExpression '?' Expression ':' Expression 
 165     LogicalAndExpression "||" LogicalOrExpression   // to (a || b) || c 
 168 LogicalAndExpression: 
 169     EqualityExpression "&&" LogicalAndExpression    // to (a && b) && c 
 173     RelationalExpression "==" RelationalExperession 
 174     RelationalExpression "!=" RelationalExperession 
 177 RelationalExpression: 
 178     MultiplicativeExpression '>' MultiplicativeExpression 
 179     MultiplicativeExpression '<' MultiplicativeExpression 
 180     MultiplicativeExpression ">=" MultiplicativeExpression 
 181     MultiplicativeExpression "<=" MultiplicativeExpression 
 182     MultiplicativeExpression 
 184 MultiplicativeExpression: 
 185     PmExpression '%' PmExpression 
 194 class wxPluralFormsToken
 
 199         T_ERROR
, T_EOF
, T_NUMBER
, T_N
, T_PLURAL
, T_NPLURALS
, T_EQUAL
, T_ASSIGN
, 
 200         T_GREATER
, T_GREATER_OR_EQUAL
, T_LESS
, T_LESS_OR_EQUAL
, 
 201         T_REMINDER
, T_NOT_EQUAL
, 
 202         T_LOGICAL_AND
, T_LOGICAL_OR
, T_QUESTION
, T_COLON
, T_SEMICOLON
, 
 203         T_LEFT_BRACKET
, T_RIGHT_BRACKET
 
 205     Type 
type() const { return m_type
; } 
 206     void setType(Type type
) { m_type 
= type
; } 
 209     Number 
number() const { return m_number
; } 
 210     void setNumber(Number num
) { m_number 
= num
; } 
 217 class wxPluralFormsScanner
 
 220     wxPluralFormsScanner(const char* s
); 
 221     const wxPluralFormsToken
& token() const { return m_token
; } 
 222     bool nextToken();  // returns false if error 
 225     wxPluralFormsToken m_token
; 
 228 wxPluralFormsScanner::wxPluralFormsScanner(const char* s
) : m_s(s
) 
 233 bool wxPluralFormsScanner::nextToken() 
 235     wxPluralFormsToken::Type type 
= wxPluralFormsToken::T_ERROR
; 
 236     while (isspace(*m_s
)) 
 242         type 
= wxPluralFormsToken::T_EOF
; 
 244     else if (isdigit(*m_s
)) 
 246         wxPluralFormsToken::Number number 
= *m_s
++ - '0'; 
 247         while (isdigit(*m_s
)) 
 249             number 
= number 
* 10 + (*m_s
++ - '0'); 
 251         m_token
.setNumber(number
); 
 252         type 
= wxPluralFormsToken::T_NUMBER
; 
 254     else if (isalpha(*m_s
)) 
 256         const char* begin 
= m_s
++; 
 257         while (isalnum(*m_s
)) 
 261         size_t size 
= m_s 
- begin
; 
 262         if (size 
== 1 && memcmp(begin
, "n", size
) == 0) 
 264             type 
= wxPluralFormsToken::T_N
; 
 266         else if (size 
== 6 && memcmp(begin
, "plural", size
) == 0) 
 268             type 
= wxPluralFormsToken::T_PLURAL
; 
 270         else if (size 
== 8 && memcmp(begin
, "nplurals", size
) == 0) 
 272             type 
= wxPluralFormsToken::T_NPLURALS
; 
 275     else if (*m_s 
== '=') 
 281             type 
= wxPluralFormsToken::T_EQUAL
; 
 285             type 
= wxPluralFormsToken::T_ASSIGN
; 
 288     else if (*m_s 
== '>') 
 294             type 
= wxPluralFormsToken::T_GREATER_OR_EQUAL
; 
 298             type 
= wxPluralFormsToken::T_GREATER
; 
 301     else if (*m_s 
== '<') 
 307             type 
= wxPluralFormsToken::T_LESS_OR_EQUAL
; 
 311             type 
= wxPluralFormsToken::T_LESS
; 
 314     else if (*m_s 
== '%') 
 317         type 
= wxPluralFormsToken::T_REMINDER
; 
 319     else if (*m_s 
== '!' && m_s
[1] == '=') 
 322         type 
= wxPluralFormsToken::T_NOT_EQUAL
; 
 324     else if (*m_s 
== '&' && m_s
[1] == '&') 
 327         type 
= wxPluralFormsToken::T_LOGICAL_AND
; 
 329     else if (*m_s 
== '|' && m_s
[1] == '|') 
 332         type 
= wxPluralFormsToken::T_LOGICAL_OR
; 
 334     else if (*m_s 
== '?') 
 337         type 
= wxPluralFormsToken::T_QUESTION
; 
 339     else if (*m_s 
== ':') 
 342         type 
= wxPluralFormsToken::T_COLON
; 
 343     } else if (*m_s 
== ';') { 
 345         type 
= wxPluralFormsToken::T_SEMICOLON
; 
 347     else if (*m_s 
== '(') 
 350         type 
= wxPluralFormsToken::T_LEFT_BRACKET
; 
 352     else if (*m_s 
== ')') 
 355         type 
= wxPluralFormsToken::T_RIGHT_BRACKET
; 
 357     m_token
.setType(type
); 
 358     return type 
!= wxPluralFormsToken::T_ERROR
; 
 361 class wxPluralFormsNode
; 
 363 // NB: Can't use wxDEFINE_SCOPED_PTR_TYPE because wxPluralFormsNode is not 
 364 //     fully defined yet: 
 365 class wxPluralFormsNodePtr
 
 368     wxPluralFormsNodePtr(wxPluralFormsNode 
*p 
= NULL
) : m_p(p
) {} 
 369     ~wxPluralFormsNodePtr(); 
 370     wxPluralFormsNode
& operator*() const { return *m_p
; } 
 371     wxPluralFormsNode
* operator->() const { return m_p
; } 
 372     wxPluralFormsNode
* get() const { return m_p
; } 
 373     wxPluralFormsNode
* release(); 
 374     void reset(wxPluralFormsNode 
*p
); 
 377     wxPluralFormsNode 
*m_p
; 
 380 class wxPluralFormsNode
 
 383     wxPluralFormsNode(const wxPluralFormsToken
& token
) : m_token(token
) {} 
 384     const wxPluralFormsToken
& token() const { return m_token
; } 
 385     const wxPluralFormsNode
* node(size_t i
) const 
 386         { return m_nodes
[i
].get(); } 
 387     void setNode(size_t i
, wxPluralFormsNode
* n
); 
 388     wxPluralFormsNode
* releaseNode(size_t i
); 
 389     wxPluralFormsToken::Number 
evaluate(wxPluralFormsToken::Number n
) const; 
 392     wxPluralFormsToken m_token
; 
 393     wxPluralFormsNodePtr m_nodes
[3]; 
 396 wxPluralFormsNodePtr::~wxPluralFormsNodePtr() 
 400 wxPluralFormsNode
* wxPluralFormsNodePtr::release() 
 402     wxPluralFormsNode 
*p 
= m_p
; 
 406 void wxPluralFormsNodePtr::reset(wxPluralFormsNode 
*p
) 
 416 void wxPluralFormsNode::setNode(size_t i
, wxPluralFormsNode
* n
) 
 421 wxPluralFormsNode
*  wxPluralFormsNode::releaseNode(size_t i
) 
 423     return m_nodes
[i
].release(); 
 426 wxPluralFormsToken::Number
 
 427 wxPluralFormsNode::evaluate(wxPluralFormsToken::Number n
) const 
 429     switch (token().type()) 
 432         case wxPluralFormsToken::T_NUMBER
: 
 433             return token().number(); 
 434         case wxPluralFormsToken::T_N
: 
 437         case wxPluralFormsToken::T_EQUAL
: 
 438             return node(0)->evaluate(n
) == node(1)->evaluate(n
); 
 439         case wxPluralFormsToken::T_NOT_EQUAL
: 
 440             return node(0)->evaluate(n
) != node(1)->evaluate(n
); 
 441         case wxPluralFormsToken::T_GREATER
: 
 442             return node(0)->evaluate(n
) > node(1)->evaluate(n
); 
 443         case wxPluralFormsToken::T_GREATER_OR_EQUAL
: 
 444             return node(0)->evaluate(n
) >= node(1)->evaluate(n
); 
 445         case wxPluralFormsToken::T_LESS
: 
 446             return node(0)->evaluate(n
) < node(1)->evaluate(n
); 
 447         case wxPluralFormsToken::T_LESS_OR_EQUAL
: 
 448             return node(0)->evaluate(n
) <= node(1)->evaluate(n
); 
 449         case wxPluralFormsToken::T_REMINDER
: 
 451                 wxPluralFormsToken::Number number 
= node(1)->evaluate(n
); 
 454                     return node(0)->evaluate(n
) % number
; 
 461         case wxPluralFormsToken::T_LOGICAL_AND
: 
 462             return node(0)->evaluate(n
) && node(1)->evaluate(n
); 
 463         case wxPluralFormsToken::T_LOGICAL_OR
: 
 464             return node(0)->evaluate(n
) || node(1)->evaluate(n
); 
 466         case wxPluralFormsToken::T_QUESTION
: 
 467             return node(0)->evaluate(n
) 
 468                 ? node(1)->evaluate(n
) 
 469                 : node(2)->evaluate(n
); 
 476 class wxPluralFormsCalculator
 
 479     wxPluralFormsCalculator() : m_nplurals(0), m_plural(0) {} 
 481     // input: number, returns msgstr index 
 482     int evaluate(int n
) const; 
 484     // input: text after "Plural-Forms:" (e.g. "nplurals=2; plural=(n != 1);"), 
 485     // if s == 0, creates default handler 
 486     // returns 0 if error 
 487     static wxPluralFormsCalculator
* make(const char* s 
= 0); 
 489     ~wxPluralFormsCalculator() {} 
 491     void  init(wxPluralFormsToken::Number nplurals
, wxPluralFormsNode
* plural
); 
 494     wxPluralFormsToken::Number m_nplurals
; 
 495     wxPluralFormsNodePtr m_plural
; 
 498 wxDEFINE_SCOPED_PTR_TYPE(wxPluralFormsCalculator
) 
 500 void wxPluralFormsCalculator::init(wxPluralFormsToken::Number nplurals
, 
 501                                    wxPluralFormsNode
* plural
) 
 503     m_nplurals 
= nplurals
; 
 504     m_plural
.reset(plural
); 
 507 int wxPluralFormsCalculator::evaluate(int n
) const 
 509     if (m_plural
.get() == 0) 
 513     wxPluralFormsToken::Number number 
= m_plural
->evaluate(n
); 
 514     if (number 
< 0 || number 
> m_nplurals
) 
 522 class wxPluralFormsParser
 
 525     wxPluralFormsParser(wxPluralFormsScanner
& scanner
) : m_scanner(scanner
) {} 
 526     bool parse(wxPluralFormsCalculator
& rCalculator
); 
 529     wxPluralFormsNode
* parsePlural(); 
 530     // stops at T_SEMICOLON, returns 0 if error 
 531     wxPluralFormsScanner
& m_scanner
; 
 532     const wxPluralFormsToken
& token() const; 
 535     wxPluralFormsNode
* expression(); 
 536     wxPluralFormsNode
* logicalOrExpression(); 
 537     wxPluralFormsNode
* logicalAndExpression(); 
 538     wxPluralFormsNode
* equalityExpression(); 
 539     wxPluralFormsNode
* multiplicativeExpression(); 
 540     wxPluralFormsNode
* relationalExpression(); 
 541     wxPluralFormsNode
* pmExpression(); 
 544 bool wxPluralFormsParser::parse(wxPluralFormsCalculator
& rCalculator
) 
 546     if (token().type() != wxPluralFormsToken::T_NPLURALS
) 
 550     if (token().type() != wxPluralFormsToken::T_ASSIGN
) 
 554     if (token().type() != wxPluralFormsToken::T_NUMBER
) 
 556     wxPluralFormsToken::Number nplurals 
= token().number(); 
 559     if (token().type() != wxPluralFormsToken::T_SEMICOLON
) 
 563     if (token().type() != wxPluralFormsToken::T_PLURAL
) 
 567     if (token().type() != wxPluralFormsToken::T_ASSIGN
) 
 571     wxPluralFormsNode
* plural 
= parsePlural(); 
 574     if (token().type() != wxPluralFormsToken::T_SEMICOLON
) 
 578     if (token().type() != wxPluralFormsToken::T_EOF
) 
 580     rCalculator
.init(nplurals
, plural
); 
 584 wxPluralFormsNode
* wxPluralFormsParser::parsePlural() 
 586     wxPluralFormsNode
* p 
= expression(); 
 591     wxPluralFormsNodePtr 
n(p
); 
 592     if (token().type() != wxPluralFormsToken::T_SEMICOLON
) 
 599 const wxPluralFormsToken
& wxPluralFormsParser::token() const 
 601     return m_scanner
.token(); 
 604 bool wxPluralFormsParser::nextToken() 
 606     if (!m_scanner
.nextToken()) 
 611 wxPluralFormsNode
* wxPluralFormsParser::expression() 
 613     wxPluralFormsNode
* p 
= logicalOrExpression(); 
 616     wxPluralFormsNodePtr 
n(p
); 
 617     if (token().type() == wxPluralFormsToken::T_QUESTION
) 
 619         wxPluralFormsNodePtr 
qn(new wxPluralFormsNode(token())); 
 630         if (token().type() != wxPluralFormsToken::T_COLON
) 
 644         qn
->setNode(0, n
.release()); 
 650 wxPluralFormsNode
*wxPluralFormsParser::logicalOrExpression() 
 652     wxPluralFormsNode
* p 
= logicalAndExpression(); 
 655     wxPluralFormsNodePtr 
ln(p
); 
 656     if (token().type() == wxPluralFormsToken::T_LOGICAL_OR
) 
 658         wxPluralFormsNodePtr 
un(new wxPluralFormsNode(token())); 
 663         p 
= logicalOrExpression(); 
 668         wxPluralFormsNodePtr 
rn(p
);    // right 
 669         if (rn
->token().type() == wxPluralFormsToken::T_LOGICAL_OR
) 
 671             // see logicalAndExpression comment 
 672             un
->setNode(0, ln
.release()); 
 673             un
->setNode(1, rn
->releaseNode(0)); 
 674             rn
->setNode(0, un
.release()); 
 679         un
->setNode(0, ln
.release()); 
 680         un
->setNode(1, rn
.release()); 
 686 wxPluralFormsNode
* wxPluralFormsParser::logicalAndExpression() 
 688     wxPluralFormsNode
* p 
= equalityExpression(); 
 691     wxPluralFormsNodePtr 
ln(p
);   // left 
 692     if (token().type() == wxPluralFormsToken::T_LOGICAL_AND
) 
 694         wxPluralFormsNodePtr 
un(new wxPluralFormsNode(token()));  // up 
 699         p 
= logicalAndExpression(); 
 704         wxPluralFormsNodePtr 
rn(p
);    // right 
 705         if (rn
->token().type() == wxPluralFormsToken::T_LOGICAL_AND
) 
 707 // transform 1 && (2 && 3) -> (1 && 2) && 3 
 711             un
->setNode(0, ln
.release()); 
 712             un
->setNode(1, rn
->releaseNode(0)); 
 713             rn
->setNode(0, un
.release()); 
 717         un
->setNode(0, ln
.release()); 
 718         un
->setNode(1, rn
.release()); 
 724 wxPluralFormsNode
* wxPluralFormsParser::equalityExpression() 
 726     wxPluralFormsNode
* p 
= relationalExpression(); 
 729     wxPluralFormsNodePtr 
n(p
); 
 730     if (token().type() == wxPluralFormsToken::T_EQUAL
 
 731         || token().type() == wxPluralFormsToken::T_NOT_EQUAL
) 
 733         wxPluralFormsNodePtr 
qn(new wxPluralFormsNode(token())); 
 738         p 
= relationalExpression(); 
 744         qn
->setNode(0, n
.release()); 
 750 wxPluralFormsNode
* wxPluralFormsParser::relationalExpression() 
 752     wxPluralFormsNode
* p 
= multiplicativeExpression(); 
 755     wxPluralFormsNodePtr 
n(p
); 
 756     if (token().type() == wxPluralFormsToken::T_GREATER
 
 757             || token().type() == wxPluralFormsToken::T_LESS
 
 758             || token().type() == wxPluralFormsToken::T_GREATER_OR_EQUAL
 
 759             || token().type() == wxPluralFormsToken::T_LESS_OR_EQUAL
) 
 761         wxPluralFormsNodePtr 
qn(new wxPluralFormsNode(token())); 
 766         p 
= multiplicativeExpression(); 
 772         qn
->setNode(0, n
.release()); 
 778 wxPluralFormsNode
* wxPluralFormsParser::multiplicativeExpression() 
 780     wxPluralFormsNode
* p 
= pmExpression(); 
 783     wxPluralFormsNodePtr 
n(p
); 
 784     if (token().type() == wxPluralFormsToken::T_REMINDER
) 
 786         wxPluralFormsNodePtr 
qn(new wxPluralFormsNode(token())); 
 797         qn
->setNode(0, n
.release()); 
 803 wxPluralFormsNode
* wxPluralFormsParser::pmExpression() 
 805     wxPluralFormsNodePtr n
; 
 806     if (token().type() == wxPluralFormsToken::T_N
 
 807         || token().type() == wxPluralFormsToken::T_NUMBER
) 
 809         n
.reset(new wxPluralFormsNode(token())); 
 815     else if (token().type() == wxPluralFormsToken::T_LEFT_BRACKET
) { 
 820         wxPluralFormsNode
* p 
= expression(); 
 826         if (token().type() != wxPluralFormsToken::T_RIGHT_BRACKET
) 
 842 wxPluralFormsCalculator
* wxPluralFormsCalculator::make(const char* s
) 
 844     wxPluralFormsCalculatorPtr 
calculator(new wxPluralFormsCalculator
); 
 847         wxPluralFormsScanner 
scanner(s
); 
 848         wxPluralFormsParser 
p(scanner
); 
 849         if (!p
.parse(*calculator
)) 
 854     return calculator
.release(); 
 860 // ---------------------------------------------------------------------------- 
 861 // wxMsgCatalogFile corresponds to one disk-file message catalog. 
 863 // This is a "low-level" class and is used only by wxMsgCatalog 
 864 // ---------------------------------------------------------------------------- 
 866 WX_DECLARE_EXPORTED_STRING_HASH_MAP(wxString
, wxMessagesHash
); 
 868 class wxMsgCatalogFile
 
 875     // load the catalog from disk (szDirPrefix corresponds to language) 
 876     bool Load(const wxChar 
*szDirPrefix
, const wxChar 
*szName
, 
 877               wxPluralFormsCalculatorPtr
& rPluralFormsCalculator
); 
 879     // fills the hash with string-translation pairs 
 880     void FillHash(wxMessagesHash
& hash
, 
 881                   const wxString
& msgIdCharset
, 
 882                   bool convertEncoding
) const; 
 884     // return the charset of the strings in this catalog or empty string if 
 886     wxString 
GetCharset() const { return m_charset
; } 
 889     // this implementation is binary compatible with GNU gettext() version 0.10 
 891     // an entry in the string table 
 892     struct wxMsgTableEntry
 
 894       size_t32   nLen
;           // length of the string 
 895       size_t32   ofsString
;      // pointer to the string 
 898     // header of a .mo file 
 899     struct wxMsgCatalogHeader
 
 901       size_t32  magic
,          // offset +00:  magic id 
 902                 revision
,       //        +04:  revision 
 903                 numStrings
;     //        +08:  number of strings in the file 
 904       size_t32  ofsOrigTable
,   //        +0C:  start of original string table 
 905                 ofsTransTable
;  //        +10:  start of translated string table 
 906       size_t32  nHashSize
,      //        +14:  hash table size 
 907                 ofsHashTable
;   //        +18:  offset of hash table start 
 910     // all data is stored here, NULL if no data loaded 
 913     // amount of memory pointed to by m_pData. 
 917     size_t32          m_numStrings
;   // number of strings in this domain 
 918     wxMsgTableEntry  
*m_pOrigTable
,   // pointer to original   strings 
 919                      *m_pTransTable
;  //            translated 
 921     wxString m_charset
;               // from the message catalog header 
 924     // swap the 2 halves of 32 bit integer if needed 
 925     size_t32 
Swap(size_t32 ui
) const 
 927           return m_bSwapped 
? (ui 
<< 24) | ((ui 
& 0xff00) << 8) | 
 928                               ((ui 
>> 8) & 0xff00) | (ui 
>> 24) 
 932     const char *StringAtOfs(wxMsgTableEntry 
*pTable
, size_t32 n
) const 
 934         const wxMsgTableEntry 
* const ent 
= pTable 
+ n
; 
 936         // this check could fail for a corrupt message catalog 
 937         size_t32 ofsString 
= Swap(ent
->ofsString
); 
 938         if ( ofsString 
+ Swap(ent
->nLen
) > m_nSize
) 
 943         return (const char *)(m_pData 
+ ofsString
); 
 946     bool m_bSwapped
;   // wrong endianness? 
 948     DECLARE_NO_COPY_CLASS(wxMsgCatalogFile
) 
 952 // ---------------------------------------------------------------------------- 
 953 // wxMsgCatalog corresponds to one loaded message catalog. 
 955 // This is a "low-level" class and is used only by wxLocale (that's why 
 956 // it's designed to be stored in a linked list) 
 957 // ---------------------------------------------------------------------------- 
 962     wxMsgCatalog() { m_conv 
= NULL
; } 
 965     // load the catalog from disk (szDirPrefix corresponds to language) 
 966     bool Load(const wxString
& dirPrefix
, const wxString
& name
, 
 967               const wxString
& msgIdCharset
, bool bConvertEncoding 
= false); 
 969     // get name of the catalog 
 970     wxString 
GetName() const { return m_name
; } 
 972     // get the translated string: returns NULL if not found 
 973     const wxString 
*GetString(const wxString
& sz
, size_t n 
= size_t(-1)) const; 
 975     // public variable pointing to the next element in a linked list (or NULL) 
 976     wxMsgCatalog 
*m_pNext
; 
 979     wxMessagesHash  m_messages
; // all messages in the catalog 
 980     wxString        m_name
;     // name of the domain 
 982     // the conversion corresponding to this catalog charset if we installed it 
 986     wxPluralFormsCalculatorPtr  m_pluralFormsCalculator
; 
 989 // ---------------------------------------------------------------------------- 
 991 // ---------------------------------------------------------------------------- 
 993 // the list of the directories to search for message catalog files 
 994 static wxArrayString gs_searchPrefixes
; 
 996 // ============================================================================ 
 998 // ============================================================================ 
1000 // ---------------------------------------------------------------------------- 
1001 // wxMsgCatalogFile class 
1002 // ---------------------------------------------------------------------------- 
1004 wxMsgCatalogFile::wxMsgCatalogFile() 
1010 wxMsgCatalogFile::~wxMsgCatalogFile() 
1015 // return the directories to search for message catalogs under the given 
1016 // prefix, separated by wxPATH_SEP 
1018 wxString 
GetMsgCatalogSubdirs(const wxChar 
*prefix
, const wxChar 
*lang
) 
1020     wxString searchPath
; 
1021     searchPath 
<< prefix 
<< wxFILE_SEP_PATH 
<< lang
; 
1023     // Under Unix, the message catalogs are supposed to go into LC_MESSAGES 
1024     // subdirectory so look there too. Note that we do it on all platforms 
1025     // and not just Unix, because it doesn't cost much to look into one more 
1026     // directory and doing it this way has two important benefits: 
1027     // a) we don't break compatibility with wx-2.6 and older by stopping to 
1028     //    look in a directory where the catalogs used to be and thus silently 
1029     //    breaking apps after they are recompiled against the latest wx 
1030     // b) it makes it possible to package app's support files in the same 
1031     //    way on all target platforms 
1032     const wxString 
searchPathOrig(searchPath
); 
1033     searchPath 
<< wxFILE_SEP_PATH 
<< wxT("LC_MESSAGES") 
1034                << wxPATH_SEP 
<< searchPathOrig
; 
1039 // construct the search path for the given language 
1040 static wxString 
GetFullSearchPath(const wxChar 
*lang
) 
1042     // first take the entries explicitly added by the program 
1043     wxArrayString paths
; 
1044     paths
.reserve(gs_searchPrefixes
.size() + 1); 
1046            count 
= gs_searchPrefixes
.size(); 
1047     for ( n 
= 0; n 
< count
; n
++ ) 
1049         paths
.Add(GetMsgCatalogSubdirs(gs_searchPrefixes
[n
], lang
)); 
1054     // then look in the standard location 
1055     const wxString stdp 
= wxStandardPaths::Get(). 
1056         GetLocalizedResourcesDir(lang
, wxStandardPaths::ResourceCat_Messages
); 
1058     if ( paths
.Index(stdp
) == wxNOT_FOUND 
) 
1060 #endif // wxUSE_STDPATHS 
1062     // last look in default locations 
1064     // LC_PATH is a standard env var containing the search path for the .mo 
1066     const wxChar 
*pszLcPath 
= wxGetenv(wxT("LC_PATH")); 
1069         const wxString lcp 
= GetMsgCatalogSubdirs(pszLcPath
, lang
); 
1070         if ( paths
.Index(lcp
) == wxNOT_FOUND 
) 
1074     // also add the one from where wxWin was installed: 
1075     wxString wxp 
= wxGetInstallPrefix(); 
1078         wxp 
= GetMsgCatalogSubdirs(wxp 
+ _T("/share/locale"), lang
); 
1079         if ( paths
.Index(wxp
) == wxNOT_FOUND 
) 
1085     // finally construct the full search path 
1086     wxString searchPath
; 
1087     searchPath
.reserve(500); 
1088     count 
= paths
.size(); 
1089     for ( n 
= 0; n 
< count
; n
++ ) 
1091         searchPath 
+= paths
[n
]; 
1092         if ( n 
!= count 
- 1 ) 
1093             searchPath 
+= wxPATH_SEP
; 
1099 // open disk file and read in it's contents 
1100 bool wxMsgCatalogFile::Load(const wxChar 
*szDirPrefix
, const wxChar 
*szName
, 
1101                             wxPluralFormsCalculatorPtr
& rPluralFormsCalculator
) 
1103   wxString searchPath
; 
1106   // first look for the catalog for this language and the current locale: 
1107   // notice that we don't use the system name for the locale as this would 
1108   // force us to install catalogs in different locations depending on the 
1109   // system but always use the canonical name 
1110   wxFontEncoding encSys 
= wxLocale::GetSystemEncoding(); 
1111   if ( encSys 
!= wxFONTENCODING_SYSTEM 
) 
1113     wxString 
fullname(szDirPrefix
); 
1114     fullname 
<< _T('.') << wxFontMapperBase::GetEncodingName(encSys
); 
1115     searchPath 
<< GetFullSearchPath(fullname
) << wxPATH_SEP
; 
1117 #endif // wxUSE_FONTMAP 
1120   searchPath 
+= GetFullSearchPath(szDirPrefix
); 
1121   const wxChar 
*sublocale 
= wxStrchr(szDirPrefix
, wxT('_')); 
1124       // also add just base locale name: for things like "fr_BE" (belgium 
1125       // french) we should use "fr" if no belgium specific message catalogs 
1127       searchPath 
<< wxPATH_SEP
 
1128                  << GetFullSearchPath(wxString(szDirPrefix
). 
1129                                       Left((size_t)(sublocale 
- szDirPrefix
))); 
1132   // don't give translation errors here because the wxstd catalog might 
1133   // not yet be loaded (and it's normal) 
1135   // (we're using an object because we have several return paths) 
1137   NoTransErr noTransErr
; 
1138   wxLogVerbose(_("looking for catalog '%s' in path '%s'."), 
1139                szName
, searchPath
.c_str()); 
1140   wxLogTrace(TRACE_I18N
, _T("Looking for \"%s.mo\" in \"%s\""), 
1141              szName
, searchPath
.c_str()); 
1143   wxFileName 
fn(szName
); 
1144   fn
.SetExt(_T("mo")); 
1145   wxString strFullName
; 
1146   if ( !wxFindFileInPath(&strFullName
, searchPath
, fn
.GetFullPath()) ) { 
1147     wxLogVerbose(_("catalog file for domain '%s' not found."), szName
); 
1148     wxLogTrace(TRACE_I18N
, _T("Catalog \"%s.mo\" not found"), szName
); 
1153   wxLogVerbose(_("using catalog '%s' from '%s'."), szName
, strFullName
.c_str()); 
1154   wxLogTrace(TRACE_I18N
, _T("Using catalog \"%s\"."), strFullName
.c_str()); 
1156   wxFile 
fileMsg(strFullName
); 
1157   if ( !fileMsg
.IsOpened() ) 
1160   // get the file size (assume it is less than 4Gb...) 
1161   wxFileOffset lenFile 
= fileMsg
.Length(); 
1162   if ( lenFile 
== wxInvalidOffset 
) 
1165   size_t nSize 
= wx_truncate_cast(size_t, lenFile
); 
1166   wxASSERT_MSG( nSize 
== lenFile 
+ size_t(0), _T("message catalog bigger than 4GB?") ); 
1168   // read the whole file in memory 
1169   m_pData 
= new size_t8
[nSize
]; 
1170   if ( fileMsg
.Read(m_pData
, nSize
) != lenFile 
) { 
1176   bool bValid 
= nSize 
+ (size_t)0 > sizeof(wxMsgCatalogHeader
); 
1178   wxMsgCatalogHeader 
*pHeader 
= (wxMsgCatalogHeader 
*)m_pData
; 
1180     // we'll have to swap all the integers if it's true 
1181     m_bSwapped 
= pHeader
->magic 
== MSGCATALOG_MAGIC_SW
; 
1183     // check the magic number 
1184     bValid 
= m_bSwapped 
|| pHeader
->magic 
== MSGCATALOG_MAGIC
; 
1188     // it's either too short or has incorrect magic number 
1189     wxLogWarning(_("'%s' is not a valid message catalog."), strFullName
.c_str()); 
1196   m_numStrings  
= Swap(pHeader
->numStrings
); 
1197   m_pOrigTable  
= (wxMsgTableEntry 
*)(m_pData 
+ 
1198                    Swap(pHeader
->ofsOrigTable
)); 
1199   m_pTransTable 
= (wxMsgTableEntry 
*)(m_pData 
+ 
1200                    Swap(pHeader
->ofsTransTable
)); 
1201   m_nSize 
= (size_t32
)nSize
; 
1203   // now parse catalog's header and try to extract catalog charset and 
1204   // plural forms formula from it: 
1206   const char* headerData 
= StringAtOfs(m_pOrigTable
, 0); 
1207   if (headerData 
&& headerData
[0] == 0) 
1209       // Extract the charset: 
1210       wxString header 
= wxString::FromAscii(StringAtOfs(m_pTransTable
, 0)); 
1211       int begin 
= header
.Find(wxT("Content-Type: text/plain; charset=")); 
1212       if (begin 
!= wxNOT_FOUND
) 
1214           begin 
+= 34; //strlen("Content-Type: text/plain; charset=") 
1215           size_t end 
= header
.find('\n', begin
); 
1216           if (end 
!= size_t(-1)) 
1218               m_charset
.assign(header
, begin
, end 
- begin
); 
1219               if (m_charset 
== wxT("CHARSET")) 
1221                   // "CHARSET" is not valid charset, but lazy translator 
1226       // else: incorrectly filled Content-Type header 
1228       // Extract plural forms: 
1229       begin 
= header
.Find(wxT("Plural-Forms:")); 
1230       if (begin 
!= wxNOT_FOUND
) 
1233           size_t end 
= header
.find('\n', begin
); 
1234           if (end 
!= size_t(-1)) 
1236               wxString 
pfs(header
, begin
, end 
- begin
); 
1237               wxPluralFormsCalculator
* pCalculator 
= wxPluralFormsCalculator
 
1238                   ::make(pfs
.ToAscii()); 
1239               if (pCalculator 
!= 0) 
1241                   rPluralFormsCalculator
.reset(pCalculator
); 
1245                    wxLogVerbose(_("Cannot parse Plural-Forms:'%s'"), pfs
.c_str()); 
1249       if (rPluralFormsCalculator
.get() == NULL
) 
1251           rPluralFormsCalculator
.reset(wxPluralFormsCalculator::make()); 
1255   // everything is fine 
1259 void wxMsgCatalogFile::FillHash(wxMessagesHash
& hash
, 
1260                                 const wxString
& msgIdCharset
, 
1261                                 bool convertEncoding
) const 
1264     // this parameter doesn't make sense, we always must convert encoding in 
1266     convertEncoding 
= true; 
1268     if ( convertEncoding 
) 
1270         // determine if we need any conversion at all 
1271         wxFontEncoding encCat 
= wxFontMapperBase::GetEncodingFromName(m_charset
); 
1272         if ( encCat 
== wxLocale::GetSystemEncoding() ) 
1274             // no need to convert 
1275             convertEncoding 
= false; 
1278 #endif // wxUSE_UNICODE/wxUSE_FONTMAP 
1281     // conversion to use to convert catalog strings to the GUI encoding 
1282     wxMBConv 
*inputConv
, 
1283              *inputConvPtr 
= NULL
; // same as inputConv but safely deleteable 
1284     if ( convertEncoding 
&& !m_charset
.empty() ) 
1287         inputConv 
= new wxCSConv(m_charset
); 
1289     else // no need or not possible to convert the encoding 
1292         // we must somehow convert the narrow strings in the message catalog to 
1293         // wide strings, so use the default conversion if we have no charset 
1294         inputConv 
= wxConvCurrent
; 
1295 #else // !wxUSE_UNICODE 
1297 #endif // wxUSE_UNICODE/!wxUSE_UNICODE 
1300     // conversion to apply to msgid strings before looking them up: we only 
1301     // need it if the msgids are neither in 7 bit ASCII nor in the same 
1302     // encoding as the catalog 
1303     wxCSConv 
*sourceConv 
= msgIdCharset
.empty() || (msgIdCharset 
== m_charset
) 
1305                             : new wxCSConv(msgIdCharset
); 
1308     wxASSERT_MSG( msgIdCharset
.empty(), 
1309                   _T("non-ASCII msgid languages only supported if wxUSE_WCHAR_T=1") ); 
1311     wxEncodingConverter converter
; 
1312     if ( convertEncoding 
) 
1314         wxFontEncoding targetEnc 
= wxFONTENCODING_SYSTEM
; 
1315         wxFontEncoding enc 
= wxFontMapperBase::Get()->CharsetToEncoding(m_charset
, false); 
1316         if ( enc 
== wxFONTENCODING_SYSTEM 
) 
1318             convertEncoding 
= false; // unknown encoding 
1322             targetEnc 
= wxLocale::GetSystemEncoding(); 
1323             if (targetEnc 
== wxFONTENCODING_SYSTEM
) 
1325                 wxFontEncodingArray a 
= wxEncodingConverter::GetPlatformEquivalents(enc
); 
1327                     // no conversion needed, locale uses native encoding 
1328                     convertEncoding 
= false; 
1329                 if (a
.GetCount() == 0) 
1330                     // we don't know common equiv. under this platform 
1331                     convertEncoding 
= false; 
1336         if ( convertEncoding 
) 
1338             converter
.Init(enc
, targetEnc
); 
1341 #endif // wxUSE_WCHAR_T/!wxUSE_WCHAR_T 
1342     (void)convertEncoding
; // get rid of warnings about unused parameter 
1344     for (size_t32 i 
= 0; i 
< m_numStrings
; i
++) 
1346         const char *data 
= StringAtOfs(m_pOrigTable
, i
); 
1350         msgid 
= wxString(data
, *inputConv
); 
1353             if ( inputConv 
&& sourceConv 
) 
1354                 msgid 
= wxString(inputConv
->cMB2WC(data
), *sourceConv
); 
1358 #endif // wxUSE_UNICODE 
1360         data 
= StringAtOfs(m_pTransTable
, i
); 
1361         size_t length 
= Swap(m_pTransTable
[i
].nLen
); 
1364         while (offset 
< length
) 
1366             const char * const str 
= data 
+ offset
; 
1370             msgstr 
= wxString(str
, *inputConv
); 
1373                 msgstr 
= wxString(inputConv
->cMB2WC(str
), *wxConvUI
); 
1376 #else // !wxUSE_WCHAR_T 
1378             if ( bConvertEncoding 
) 
1379                 msgstr 
= wxString(converter
.Convert(str
)); 
1383 #endif // wxUSE_WCHAR_T/!wxUSE_WCHAR_T 
1385             if ( !msgstr
.empty() ) 
1387                 hash
[index 
== 0 ? msgid 
: msgid 
+ wxChar(index
)] = msgstr
; 
1391             offset 
+= strlen(str
) + 1; 
1398     delete inputConvPtr
; 
1399 #endif // wxUSE_WCHAR_T 
1403 // ---------------------------------------------------------------------------- 
1404 // wxMsgCatalog class 
1405 // ---------------------------------------------------------------------------- 
1407 wxMsgCatalog::~wxMsgCatalog() 
1411         if ( wxConvUI 
== m_conv 
) 
1413             // we only change wxConvUI if it points to wxConvLocal so we reset 
1414             // it back to it too 
1415             wxConvUI 
= &wxConvLocal
; 
1422 bool wxMsgCatalog::Load(const wxString
& dirPrefix
, const wxString
& name
, 
1423                         const wxString
& msgIdCharset
, bool bConvertEncoding
) 
1425     wxMsgCatalogFile file
; 
1429     if ( !file
.Load(dirPrefix
, name
, m_pluralFormsCalculator
) ) 
1432     file
.FillHash(m_messages
, msgIdCharset
, bConvertEncoding
); 
1434     // we should use a conversion compatible with the message catalog encoding 
1435     // in the GUI if we don't convert the strings to the current conversion but 
1436     // as the encoding is global, only change it once, otherwise we could get 
1437     // into trouble if we use several message catalogs with different encodings 
1439     // this is, of course, a hack but it at least allows the program to use 
1440     // message catalogs in any encodings without asking the user to change his 
1442     if ( !bConvertEncoding 
&& 
1443             !file
.GetCharset().empty() && 
1444                 wxConvUI 
== &wxConvLocal 
) 
1447         m_conv 
= new wxCSConv(file
.GetCharset()); 
1453 const wxString 
*wxMsgCatalog::GetString(const wxString
& str
, size_t n
) const 
1456     if (n 
!= size_t(-1)) 
1458         index 
= m_pluralFormsCalculator
->evaluate(n
); 
1460     wxMessagesHash::const_iterator i
; 
1463         i 
= m_messages
.find(wxString(str
) + wxChar(index
));   // plural 
1467         i 
= m_messages
.find(str
); 
1470     if ( i 
!= m_messages
.end() ) 
1478 // ---------------------------------------------------------------------------- 
1480 // ---------------------------------------------------------------------------- 
1482 #include "wx/arrimpl.cpp" 
1483 WX_DECLARE_EXPORTED_OBJARRAY(wxLanguageInfo
, wxLanguageInfoArray
); 
1484 WX_DEFINE_OBJARRAY(wxLanguageInfoArray
) 
1486 wxLanguageInfoArray 
*wxLocale::ms_languagesDB 
= NULL
; 
1488 /*static*/ void wxLocale::CreateLanguagesDB() 
1490     if (ms_languagesDB 
== NULL
) 
1492         ms_languagesDB 
= new wxLanguageInfoArray
; 
1497 /*static*/ void wxLocale::DestroyLanguagesDB() 
1499     delete ms_languagesDB
; 
1500     ms_languagesDB 
= NULL
; 
1504 void wxLocale::DoCommonInit() 
1506   m_pszOldLocale 
= NULL
; 
1508   m_pOldLocale 
= wxSetLocale(this); 
1511   m_language 
= wxLANGUAGE_UNKNOWN
; 
1512   m_initialized 
= false; 
1515 // NB: this function has (desired) side effect of changing current locale 
1516 bool wxLocale::Init(const wxString
& name
, 
1517                     const wxString
& shortName
, 
1518                     const wxString
& locale
, 
1520                     bool            bConvertEncoding
) 
1522   wxASSERT_MSG( !m_initialized
, 
1523                 _T("you can't call wxLocale::Init more than once") ); 
1525   m_initialized 
= true; 
1527   m_strShort 
= shortName
; 
1528   m_bConvertEncoding 
= bConvertEncoding
; 
1529   m_language 
= wxLANGUAGE_UNKNOWN
; 
1531   // change current locale (default: same as long name) 
1532   wxString 
szLocale(locale
); 
1533   if ( szLocale
.empty() ) 
1535     // the argument to setlocale() 
1536     szLocale 
= shortName
; 
1538     wxCHECK_MSG( !szLocale
.empty(), false, 
1539                  _T("no locale to set in wxLocale::Init()") ); 
1543   // FIXME: I'm guessing here 
1544   wxChar localeName
[256]; 
1545   int ret 
= GetLocaleInfo(LOCALE_USER_DEFAULT
, LOCALE_SLANGUAGE
, localeName
, 
1549     m_pszOldLocale 
= wxStrdup(localeName
); 
1552     m_pszOldLocale 
= NULL
; 
1554   // TODO: how to find languageId 
1555   // SetLocaleInfo(languageId, SORT_DEFAULT, localeName); 
1557   wxMB2WXbuf oldLocale 
= wxSetlocale(LC_ALL
, szLocale
); 
1559       m_pszOldLocale 
= wxStrdup(oldLocale
); 
1561       m_pszOldLocale 
= NULL
; 
1564   if ( m_pszOldLocale 
== NULL 
) 
1565     wxLogError(_("locale '%s' can not be set."), szLocale
); 
1567   // the short name will be used to look for catalog files as well, 
1568   // so we need something here 
1569   if ( m_strShort
.empty() ) { 
1570     // FIXME I don't know how these 2 letter abbreviations are formed, 
1571     //       this wild guess is surely wrong 
1572     if ( !szLocale
.empty() ) 
1574         m_strShort 
+= (wxChar
)wxTolower(szLocale
[0]); 
1575         if ( szLocale
.length() > 1 ) 
1576             m_strShort 
+= (wxChar
)wxTolower(szLocale
[1]); 
1580   // load the default catalog with wxWidgets standard messages 
1585     bOk 
= AddCatalog(wxT("wxstd")); 
1587     // there may be a catalog with toolkit specific overrides, it is not 
1588     // an error if this does not exist 
1591       wxString 
port(wxPlatformInfo::Get().GetPortIdName()); 
1592       if ( !port
.empty() ) 
1594         AddCatalog(port
.BeforeFirst(wxT('/')).MakeLower()); 
1603 #if defined(__UNIX__) && wxUSE_UNICODE && !defined(__WXMAC__) 
1604 static wxWCharBuffer 
wxSetlocaleTryUTF8(int c
, const wxChar 
*lc
) 
1608     // NB: We prefer to set UTF-8 locale if it's possible and only fall back to 
1609     //     non-UTF-8 locale if it fails 
1611     if ( lc 
&& lc
[0] != 0 ) 
1615         buf2 
= buf 
+ wxT(".UTF-8"); 
1616         l 
= wxSetlocale(c
, buf2
.c_str()); 
1619             buf2 
= buf 
+ wxT(".utf-8"); 
1620             l 
= wxSetlocale(c
, buf2
.c_str()); 
1624             buf2 
= buf 
+ wxT(".UTF8"); 
1625             l 
= wxSetlocale(c
, buf2
.c_str()); 
1629             buf2 
= buf 
+ wxT(".utf8"); 
1630             l 
= wxSetlocale(c
, buf2
.c_str()); 
1634     // if we can't set UTF-8 locale, try non-UTF-8 one: 
1636         l 
= wxSetlocale(c
, lc
); 
1641 #define wxSetlocaleTryUTF8(c, lc)  wxSetlocale(c, lc) 
1644 bool wxLocale::Init(int language
, int flags
) 
1646     int lang 
= language
; 
1647     if (lang 
== wxLANGUAGE_DEFAULT
) 
1649         // auto detect the language 
1650         lang 
= GetSystemLanguage(); 
1653     // We failed to detect system language, so we will use English: 
1654     if (lang 
== wxLANGUAGE_UNKNOWN
) 
1659     const wxLanguageInfo 
*info 
= GetLanguageInfo(lang
); 
1661     // Unknown language: 
1664         wxLogError(wxT("Unknown language %i."), lang
); 
1668     wxString name 
= info
->Description
; 
1669     wxString canonical 
= info
->CanonicalName
; 
1673 #if defined(__OS2__) 
1674     wxMB2WXbuf retloc 
= wxSetlocale(LC_ALL 
, wxEmptyString
); 
1675 #elif defined(__UNIX__) && !defined(__WXMAC__) 
1676     if (language 
!= wxLANGUAGE_DEFAULT
) 
1677         locale 
= info
->CanonicalName
; 
1679     wxMB2WXbuf retloc 
= wxSetlocaleTryUTF8(LC_ALL
, locale
); 
1681     const wxString langOnly 
= locale
.Left(2); 
1684         // Some C libraries don't like xx_YY form and require xx only 
1685         retloc 
= wxSetlocaleTryUTF8(LC_ALL
, langOnly
); 
1689     // some systems (e.g. FreeBSD and HP-UX) don't have xx_YY aliases but 
1690     // require the full xx_YY.encoding form, so try using UTF-8 because this is 
1691     // the only thing we can do generically 
1693     // TODO: add encodings applicable to each language to the lang DB and try 
1694     //       them all in turn here 
1697         const wxChar 
**names 
= 
1698             wxFontMapperBase::GetAllEncodingNames(wxFONTENCODING_UTF8
); 
1701             retloc 
= wxSetlocale(LC_ALL
, locale 
+ _T('.') + *names
++); 
1706 #endif // wxUSE_FONTMAP 
1710         // Some C libraries (namely glibc) still use old ISO 639, 
1711         // so will translate the abbrev for them 
1713         if ( langOnly 
== wxT("he") ) 
1714             localeAlt 
= wxT("iw") + locale
.Mid(3); 
1715         else if ( langOnly 
== wxT("id") ) 
1716             localeAlt 
= wxT("in") + locale
.Mid(3); 
1717         else if ( langOnly 
== wxT("yi") ) 
1718             localeAlt 
= wxT("ji") + locale
.Mid(3); 
1719         else if ( langOnly 
== wxT("nb") ) 
1720             localeAlt 
= wxT("no_NO"); 
1721         else if ( langOnly 
== wxT("nn") ) 
1722             localeAlt 
= wxT("no_NY"); 
1724         if ( !localeAlt
.empty() ) 
1726             retloc 
= wxSetlocaleTryUTF8(LC_ALL
, localeAlt
); 
1728                 retloc 
= wxSetlocaleTryUTF8(LC_ALL
, localeAlt
.Left(2)); 
1734         wxLogError(wxT("Cannot set locale to '%s'."), locale
.c_str()); 
1739     // at least in AIX 5.2 libc is buggy and the string returned from 
1740     // setlocale(LC_ALL) can't be passed back to it because it returns 6 
1741     // strings (one for each locale category), i.e. for C locale we get back 
1744     // this contradicts IBM own docs but this is not of much help, so just work 
1745     // around it in the crudest possible manner 
1746     wxChar 
*p 
= wxStrchr((wxChar 
*)retloc
, _T(' ')); 
1751 #elif defined(__WIN32__) 
1753     #if wxUSE_UNICODE && (defined(__VISUALC__) || defined(__MINGW32__)) 
1754         // NB: setlocale() from msvcrt.dll (used by VC++ and Mingw) 
1755         //     can't set locale to language that can only be written using 
1756         //     Unicode.  Therefore wxSetlocale call failed, but we don't want 
1757         //     to report it as an error -- so that at least message catalogs 
1758         //     can be used. Watch for code marked with 
1759         //     #ifdef SETLOCALE_FAILS_ON_UNICODE_LANGS bellow. 
1760         #define SETLOCALE_FAILS_ON_UNICODE_LANGS 
1766     wxMB2WXbuf retloc 
= wxT("C"); 
1767     if (language 
!= wxLANGUAGE_DEFAULT
) 
1769         if (info
->WinLang 
== 0) 
1771             wxLogWarning(wxT("Locale '%s' not supported by OS."), name
.c_str()); 
1772             // retloc already set to "C" 
1777                          #ifdef SETLOCALE_FAILS_ON_UNICODE_LANGS 
1781             wxUint32 lcid 
= MAKELCID(MAKELANGID(info
->WinLang
, info
->WinSublang
), 
1785             SetThreadLocale(lcid
); 
1787             // NB: we must translate LCID to CRT's setlocale string ourselves, 
1788             //     because SetThreadLocale does not modify change the 
1789             //     interpretation of setlocale(LC_ALL, "") call: 
1791             buffer
[0] = wxT('\0'); 
1792             GetLocaleInfo(lcid
, LOCALE_SENGLANGUAGE
, buffer
, 256); 
1794             if (GetLocaleInfo(lcid
, LOCALE_SENGCOUNTRY
, buffer
, 256) > 0) 
1795                 locale 
<< wxT("_") << buffer
; 
1796             if (GetLocaleInfo(lcid
, LOCALE_IDEFAULTANSICODEPAGE
, buffer
, 256) > 0) 
1798                 codepage 
= wxAtoi(buffer
); 
1800                     locale 
<< wxT(".") << buffer
; 
1804                 wxLogLastError(wxT("SetThreadLocale")); 
1805                 wxLogError(wxT("Cannot set locale to language %s."), name
.c_str()); 
1812                 retloc 
= wxSetlocale(LC_ALL
, locale
); 
1814 #ifdef SETLOCALE_FAILS_ON_UNICODE_LANGS 
1815                 if (codepage 
== 0 && (const wxChar
*)retloc 
== NULL
) 
1827         retloc 
= wxSetlocale(LC_ALL
, wxEmptyString
); 
1831 #ifdef SETLOCALE_FAILS_ON_UNICODE_LANGS 
1832         if ((const wxChar
*)retloc 
== NULL
) 
1835             if (GetLocaleInfo(LOCALE_USER_DEFAULT
, 
1836                               LOCALE_IDEFAULTANSICODEPAGE
, buffer
, 16) > 0 && 
1837                  wxStrcmp(buffer
, wxT("0")) == 0) 
1847         wxLogError(wxT("Cannot set locale to language %s."), name
.c_str()); 
1850 #elif defined(__WXMAC__) 
1851     if (lang 
== wxLANGUAGE_DEFAULT
) 
1852         locale 
= wxEmptyString
; 
1854         locale 
= info
->CanonicalName
; 
1856     wxMB2WXbuf retloc 
= wxSetlocale(LC_ALL
, locale
); 
1860         // Some C libraries don't like xx_YY form and require xx only 
1861         retloc 
= wxSetlocale(LC_ALL
, locale
.Mid(0,2)); 
1865         wxLogError(wxT("Cannot set locale to '%s'."), locale
.c_str()); 
1871     #define WX_NO_LOCALE_SUPPORT 
1874 #ifndef WX_NO_LOCALE_SUPPORT 
1875     bool ret 
= Init(name
, canonical
, retloc
, 
1876                     (flags 
& wxLOCALE_LOAD_DEFAULT
) != 0, 
1877                     (flags 
& wxLOCALE_CONV_ENCODING
) != 0); 
1879     if (IsOk()) // setlocale() succeeded 
1883 #endif // !WX_NO_LOCALE_SUPPORT 
1888 void wxLocale::AddCatalogLookupPathPrefix(const wxString
& prefix
) 
1890     if ( gs_searchPrefixes
.Index(prefix
) == wxNOT_FOUND 
) 
1892         gs_searchPrefixes
.Add(prefix
); 
1894     //else: already have it 
1897 /*static*/ int wxLocale::GetSystemLanguage() 
1899     CreateLanguagesDB(); 
1901     // init i to avoid compiler warning 
1903            count 
= ms_languagesDB
->GetCount(); 
1905 #if defined(__UNIX__) && !defined(__WXMAC__) 
1906     // first get the string identifying the language from the environment 
1908     if (!wxGetEnv(wxT("LC_ALL"), &langFull
) && 
1909         !wxGetEnv(wxT("LC_MESSAGES"), &langFull
) && 
1910         !wxGetEnv(wxT("LANG"), &langFull
)) 
1912         // no language specified, treat it as English 
1913         return wxLANGUAGE_ENGLISH_US
; 
1916     if ( langFull 
== _T("C") || langFull 
== _T("POSIX") ) 
1918         // default C locale is English too 
1919         return wxLANGUAGE_ENGLISH_US
; 
1922     // the language string has the following form 
1924     //      lang[_LANG][.encoding][@modifier] 
1926     // (see environ(5) in the Open Unix specification) 
1928     // where lang is the primary language, LANG is a sublang/territory, 
1929     // encoding is the charset to use and modifier "allows the user to select 
1930     // a specific instance of localization data within a single category" 
1932     // for example, the following strings are valid: 
1937     //      de_DE.iso88591@euro 
1939     // for now we don't use the encoding, although we probably should (doing 
1940     // translations of the msg catalogs on the fly as required) (TODO) 
1942     // we don't use the modifiers neither but we probably should translate 
1943     // "euro" into iso885915 
1944     size_t posEndLang 
= langFull
.find_first_of(_T("@.")); 
1945     if ( posEndLang 
!= wxString::npos 
) 
1947         langFull
.Truncate(posEndLang
); 
1950     // in addition to the format above, we also can have full language names 
1951     // in LANG env var - for example, SuSE is known to use LANG="german" - so 
1954     // do we have just the language (or sublang too)? 
1955     bool justLang 
= langFull
.length() == LEN_LANG
; 
1957          (langFull
.length() == LEN_FULL 
&& langFull
[LEN_LANG
] == wxT('_')) ) 
1959         // 0. Make sure the lang is according to latest ISO 639 
1960         //    (this is necessary because glibc uses iw and in instead 
1961         //    of he and id respectively). 
1963         // the language itself (second part is the dialect/sublang) 
1964         wxString langOrig 
= ExtractLang(langFull
); 
1967         if ( langOrig 
== wxT("iw")) 
1969         else if (langOrig 
== wxT("in")) 
1971         else if (langOrig 
== wxT("ji")) 
1973         else if (langOrig 
== wxT("no_NO")) 
1974             lang 
= wxT("nb_NO"); 
1975         else if (langOrig 
== wxT("no_NY")) 
1976             lang 
= wxT("nn_NO"); 
1977         else if (langOrig 
== wxT("no")) 
1978             lang 
= wxT("nb_NO"); 
1982         // did we change it? 
1983         if ( lang 
!= langOrig 
) 
1985             langFull 
= lang 
+ ExtractNotLang(langFull
); 
1988         // 1. Try to find the language either as is: 
1989         for ( i 
= 0; i 
< count
; i
++ ) 
1991             if ( ms_languagesDB
->Item(i
).CanonicalName 
== langFull 
) 
1997         // 2. If langFull is of the form xx_YY, try to find xx: 
1998         if ( i 
== count 
&& !justLang 
) 
2000             for ( i 
= 0; i 
< count
; i
++ ) 
2002                 if ( ms_languagesDB
->Item(i
).CanonicalName 
== lang 
) 
2009         // 3. If langFull is of the form xx, try to find any xx_YY record: 
2010         if ( i 
== count 
&& justLang 
) 
2012             for ( i 
= 0; i 
< count
; i
++ ) 
2014                 if ( ExtractLang(ms_languagesDB
->Item(i
).CanonicalName
) 
2022     else // not standard format 
2024         // try to find the name in verbose description 
2025         for ( i 
= 0; i 
< count
; i
++ ) 
2027             if (ms_languagesDB
->Item(i
).Description
.CmpNoCase(langFull
) == 0) 
2033 #elif defined(__WXMAC__) 
2034     const wxChar 
* lc 
= NULL 
; 
2035     long lang 
= GetScriptVariable( smSystemScript
, smScriptLang
) ; 
2036     switch( GetScriptManagerVariable( smRegionCode 
) ) { 
2052       case verNetherlands 
: 
2107       // _CY is not part of wx, so we have to translate according to the system language 
2108         if ( lang 
== langGreek 
) { 
2111         else if ( lang 
== langTurkish 
) { 
2118       case verYugoCroatian
: 
2124       case verPakistanUrdu
: 
2127       case verTurkishModified
: 
2130       case verItalianSwiss
: 
2133       case verInternational
: 
2194       case verByeloRussian
: 
2216         lc 
= wxT("pt_BR ") ; 
2224       case verScottishGaelic
: 
2239       case verIrishGaelicScript
: 
2254       case verSpLatinAmerica
: 
2260       case verFrenchUniversal
: 
2311   for ( i 
= 0; i 
< count
; i
++ ) 
2313       if ( ms_languagesDB
->Item(i
).CanonicalName 
== lc 
) 
2319 #elif defined(__WIN32__) 
2320     LCID lcid 
= GetUserDefaultLCID(); 
2323         wxUint32 lang 
= PRIMARYLANGID(LANGIDFROMLCID(lcid
)); 
2324         wxUint32 sublang 
= SUBLANGID(LANGIDFROMLCID(lcid
)); 
2326         for ( i 
= 0; i 
< count
; i
++ ) 
2328             if (ms_languagesDB
->Item(i
).WinLang 
== lang 
&& 
2329                 ms_languagesDB
->Item(i
).WinSublang 
== sublang
) 
2335     //else: leave wxlang == wxLANGUAGE_UNKNOWN 
2336 #endif // Unix/Win32 
2340         // we did find a matching entry, use it 
2341         return ms_languagesDB
->Item(i
).Language
; 
2344     // no info about this language in the database 
2345     return wxLANGUAGE_UNKNOWN
; 
2348 // ---------------------------------------------------------------------------- 
2350 // ---------------------------------------------------------------------------- 
2352 // this is a bit strange as under Windows we get the encoding name using its 
2353 // numeric value and under Unix we do it the other way round, but this just 
2354 // reflects the way different systems provide the encoding info 
2357 wxString 
wxLocale::GetSystemEncodingName() 
2361 #if defined(__WIN32__) && !defined(__WXMICROWIN__) 
2362     // FIXME: what is the error return value for GetACP()? 
2363     UINT codepage 
= ::GetACP(); 
2364     encname
.Printf(_T("windows-%u"), codepage
); 
2365 #elif defined(__WXMAC__) 
2366     // default is just empty string, this resolves to the default system 
2368 #elif defined(__UNIX_LIKE__) 
2370 #if defined(HAVE_LANGINFO_H) && defined(CODESET) 
2371     // GNU libc provides current character set this way (this conforms 
2373     char *oldLocale 
= strdup(setlocale(LC_CTYPE
, NULL
)); 
2374     setlocale(LC_CTYPE
, ""); 
2375     const char *alang 
= nl_langinfo(CODESET
); 
2376     setlocale(LC_CTYPE
, oldLocale
); 
2381         encname 
= wxString::FromAscii( alang 
); 
2383     else // nl_langinfo() failed 
2384 #endif // HAVE_LANGINFO_H 
2386         // if we can't get at the character set directly, try to see if it's in 
2387         // the environment variables (in most cases this won't work, but I was 
2389         char *lang 
= getenv( "LC_ALL"); 
2390         char *dot 
= lang 
? strchr(lang
, '.') : (char *)NULL
; 
2393             lang 
= getenv( "LC_CTYPE" ); 
2395                 dot 
= strchr(lang
, '.' ); 
2399             lang 
= getenv( "LANG"); 
2401                 dot 
= strchr(lang
, '.'); 
2406             encname 
= wxString::FromAscii( dot
+1 ); 
2409 #endif // Win32/Unix 
2415 wxFontEncoding 
wxLocale::GetSystemEncoding() 
2417 #if defined(__WIN32__) && !defined(__WXMICROWIN__) 
2418     UINT codepage 
= ::GetACP(); 
2420     // wxWidgets only knows about CP1250-1257, 874, 932, 936, 949, 950 
2421     if ( codepage 
>= 1250 && codepage 
<= 1257 ) 
2423         return (wxFontEncoding
)(wxFONTENCODING_CP1250 
+ codepage 
- 1250); 
2426     if ( codepage 
== 874 ) 
2428         return wxFONTENCODING_CP874
; 
2431     if ( codepage 
== 932 ) 
2433         return wxFONTENCODING_CP932
; 
2436     if ( codepage 
== 936 ) 
2438         return wxFONTENCODING_CP936
; 
2441     if ( codepage 
== 949 ) 
2443         return wxFONTENCODING_CP949
; 
2446     if ( codepage 
== 950 ) 
2448         return wxFONTENCODING_CP950
; 
2450 #elif defined(__WXMAC__) 
2451     TextEncoding encoding 
= 0 ; 
2453     encoding 
= CFStringGetSystemEncoding() ; 
2455     UpgradeScriptInfoToTextEncoding ( smSystemScript 
, kTextLanguageDontCare 
, kTextRegionDontCare 
, NULL 
, &encoding 
) ; 
2457     return wxMacGetFontEncFromSystemEnc( encoding 
) ; 
2458 #elif defined(__UNIX_LIKE__) && wxUSE_FONTMAP 
2459     const wxString encname 
= GetSystemEncodingName(); 
2460     if ( !encname
.empty() ) 
2462         wxFontEncoding enc 
= wxFontMapperBase::GetEncodingFromName(encname
); 
2464         // on some modern Linux systems (RedHat 8) the default system locale 
2465         // is UTF8 -- but it isn't supported by wxGTK1 in ANSI build at all so 
2466         // don't even try to use it in this case 
2467 #if !wxUSE_UNICODE && \ 
2468         ((defined(__WXGTK__) && !defined(__WXGTK20__)) || defined(__WXMOTIF__)) 
2469         if ( enc 
== wxFONTENCODING_UTF8 
) 
2471             // the most similar supported encoding... 
2472             enc 
= wxFONTENCODING_ISO8859_1
; 
2474 #endif // !wxUSE_UNICODE 
2476         // GetEncodingFromName() returns wxFONTENCODING_DEFAULT for C locale 
2477         // (a.k.a. US-ASCII) which is arguably a bug but keep it like this for 
2478         // backwards compatibility and just take care to not return 
2479         // wxFONTENCODING_DEFAULT from here as this surely doesn't make sense 
2480         if ( enc 
== wxFONTENCODING_DEFAULT 
) 
2482             // we don't have wxFONTENCODING_ASCII, so use the closest one 
2483             return wxFONTENCODING_ISO8859_1
; 
2486         if ( enc 
!= wxFONTENCODING_MAX 
) 
2490         //else: return wxFONTENCODING_SYSTEM below 
2492 #endif // Win32/Unix 
2494     return wxFONTENCODING_SYSTEM
; 
2498 void wxLocale::AddLanguage(const wxLanguageInfo
& info
) 
2500     CreateLanguagesDB(); 
2501     ms_languagesDB
->Add(info
); 
2505 const wxLanguageInfo 
*wxLocale::GetLanguageInfo(int lang
) 
2507     CreateLanguagesDB(); 
2509     // calling GetLanguageInfo(wxLANGUAGE_DEFAULT) is a natural thing to do, so 
2511     if ( lang 
== wxLANGUAGE_DEFAULT 
) 
2512         lang 
= GetSystemLanguage(); 
2514     const size_t count 
= ms_languagesDB
->GetCount(); 
2515     for ( size_t i 
= 0; i 
< count
; i
++ ) 
2517         if ( ms_languagesDB
->Item(i
).Language 
== lang 
) 
2519             // We need to create a temporary here in order to make this work with BCC in final build mode 
2520             wxLanguageInfo 
*ptr 
= &ms_languagesDB
->Item(i
); 
2529 wxString 
wxLocale::GetLanguageName(int lang
) 
2531     const wxLanguageInfo 
*info 
= GetLanguageInfo(lang
); 
2533         return wxEmptyString
; 
2535         return info
->Description
; 
2539 const wxLanguageInfo 
*wxLocale::FindLanguageInfo(const wxString
& locale
) 
2541     CreateLanguagesDB(); 
2543     const wxLanguageInfo 
*infoRet 
= NULL
; 
2545     const size_t count 
= ms_languagesDB
->GetCount(); 
2546     for ( size_t i 
= 0; i 
< count
; i
++ ) 
2548         const wxLanguageInfo 
*info 
= &ms_languagesDB
->Item(i
); 
2550         if ( wxStricmp(locale
, info
->CanonicalName
) == 0 || 
2551                 wxStricmp(locale
, info
->Description
) == 0 ) 
2553             // exact match, stop searching 
2558         if ( wxStricmp(locale
, info
->CanonicalName
.BeforeFirst(_T('_'))) == 0 ) 
2560             // a match -- but maybe we'll find an exact one later, so continue 
2563             // OTOH, maybe we had already found a language match and in this 
2564             // case don't overwrite it becauce the entry for the default 
2565             // country always appears first in ms_languagesDB 
2574 wxString 
wxLocale::GetSysName() const 
2578     return wxSetlocale(LC_ALL
, NULL
); 
2580     return wxEmptyString
; 
2585 wxLocale::~wxLocale() 
2588     wxMsgCatalog 
*pTmpCat
; 
2589     while ( m_pMsgCat 
!= NULL 
) { 
2590         pTmpCat 
= m_pMsgCat
; 
2591         m_pMsgCat 
= m_pMsgCat
->m_pNext
; 
2595     // restore old locale pointer 
2596     wxSetLocale(m_pOldLocale
); 
2600     wxSetlocale(LC_ALL
, m_pszOldLocale
); 
2602     free((wxChar 
*)m_pszOldLocale
);     // const_cast 
2605 // get the translation of given string in current locale 
2606 const wxString
& wxLocale::GetString(const wxString
& origString
, 
2607                                     const wxString
& domain
) const 
2609     return GetString(origString
, origString
, size_t(-1), domain
); 
2612 const wxString
& wxLocale::GetString(const wxString
& origString
, 
2613                                     const wxString
& origString2
, 
2615                                     const wxString
& domain
) const 
2617     if ( origString
.empty() ) 
2618         return GetUntranslatedString(origString
); 
2620     const wxString 
*trans 
= NULL
; 
2621     wxMsgCatalog 
*pMsgCat
; 
2623     if ( !domain
.empty() ) 
2625         pMsgCat 
= FindCatalog(domain
); 
2627         // does the catalog exist? 
2628         if ( pMsgCat 
!= NULL 
) 
2629             trans 
= pMsgCat
->GetString(origString
, n
); 
2633         // search in all domains 
2634         for ( pMsgCat 
= m_pMsgCat
; pMsgCat 
!= NULL
; pMsgCat 
= pMsgCat
->m_pNext 
) 
2636             trans 
= pMsgCat
->GetString(origString
, n
); 
2637             if ( trans 
!= NULL 
)   // take the first found 
2642     if ( trans 
== NULL 
) 
2645         if ( !NoTransErr::Suppress() ) 
2647             NoTransErr noTransErr
; 
2649             wxLogTrace(TRACE_I18N
, 
2650                        _T("string \"%s\"[%ld] not found in %slocale '%s'."), 
2651                        origString
, (long)n
, 
2653                          ? (const wxChar
*)wxString::Format(_T("domain '%s' "), domain
).c_str() 
2655                        m_strLocale
.c_str()); 
2657 #endif // __WXDEBUG__ 
2659         if (n 
== size_t(-1)) 
2660             return GetUntranslatedString(origString
); 
2662             return GetUntranslatedString(n 
== 1 ? origString 
: origString2
); 
2668 WX_DECLARE_HASH_SET(wxString
, wxStringHash
, wxStringEqual
, 
2669                     wxLocaleUntranslatedStrings
); 
2672 const wxString
& wxLocale::GetUntranslatedString(const wxString
& str
) 
2674     static wxLocaleUntranslatedStrings s_strings
; 
2676     wxLocaleUntranslatedStrings::iterator i 
= s_strings
.find(str
); 
2677     if ( i 
== s_strings
.end() ) 
2678         return *s_strings
.insert(str
).first
; 
2683 wxString 
wxLocale::GetHeaderValue(const wxString
& header
, 
2684                                   const wxString
& domain
) const 
2686     if ( header
.empty() ) 
2687         return wxEmptyString
; 
2689     const wxString 
*trans 
= NULL
; 
2690     wxMsgCatalog 
*pMsgCat
; 
2692     if ( !domain
.empty() ) 
2694         pMsgCat 
= FindCatalog(domain
); 
2696         // does the catalog exist? 
2697         if ( pMsgCat 
== NULL 
) 
2698             return wxEmptyString
; 
2700         trans 
= pMsgCat
->GetString(wxEmptyString
, (size_t)-1); 
2704         // search in all domains 
2705         for ( pMsgCat 
= m_pMsgCat
; pMsgCat 
!= NULL
; pMsgCat 
= pMsgCat
->m_pNext 
) 
2707             trans 
= pMsgCat
->GetString(wxEmptyString
, (size_t)-1); 
2708             if ( trans 
!= NULL 
)   // take the first found 
2713     if ( !trans 
|| trans
->empty() ) 
2714       return wxEmptyString
; 
2716     size_t found 
= trans
->find(header
); 
2717     if ( found 
== wxString::npos 
) 
2718       return wxEmptyString
; 
2720     found 
+= header
.length() + 2 /* ': ' */; 
2722     // Every header is separated by \n 
2724     size_t endLine 
= trans
->find(wxT('\n'), found
); 
2725     size_t len 
= (endLine 
== wxString::npos
) ? 
2726                  wxString::npos 
: (endLine 
- found
); 
2728     return trans
->substr(found
, len
); 
2732 // find catalog by name in a linked list, return NULL if !found 
2733 wxMsgCatalog 
*wxLocale::FindCatalog(const wxString
& domain
) const 
2735     // linear search in the linked list 
2736     wxMsgCatalog 
*pMsgCat
; 
2737     for ( pMsgCat 
= m_pMsgCat
; pMsgCat 
!= NULL
; pMsgCat 
= pMsgCat
->m_pNext 
) 
2739         if ( pMsgCat
->GetName() == domain 
) 
2746 // check if the given locale is provided by OS and C run time 
2748 bool wxLocale::IsAvailable(int lang
) 
2750     const wxLanguageInfo 
*info 
= wxLocale::GetLanguageInfo(lang
); 
2751     wxCHECK_MSG( info
, false, _T("invalid language") ); 
2753 #if defined(__WIN32__) 
2754     if ( !info
->WinLang 
) 
2757     if ( !::IsValidLocale
 
2759                 MAKELCID(MAKELANGID(info
->WinLang
, info
->WinSublang
), 
2765 #elif defined(__UNIX__) 
2767     // Test if setting the locale works, then set it back.  
2768     wxMB2WXbuf oldLocale 
= wxSetlocale(LC_ALL
, wxEmptyString
); 
2769     wxMB2WXbuf tmp 
= wxSetlocaleTryUTF8(LC_ALL
, info
->CanonicalName
); 
2772         // Some C libraries don't like xx_YY form and require xx only 
2773         tmp 
= wxSetlocaleTryUTF8(LC_ALL
, info
->CanonicalName
.Left(2)); 
2777     // restore the original locale 
2778     wxSetlocale(LC_ALL
, oldLocale
);     
2784 // check if the given catalog is loaded 
2785 bool wxLocale::IsLoaded(const wxString
& szDomain
) const 
2787   return FindCatalog(szDomain
) != NULL
; 
2790 // add a catalog to our linked list 
2791 bool wxLocale::AddCatalog(const wxString
& szDomain
) 
2793     return AddCatalog(szDomain
, wxLANGUAGE_ENGLISH_US
, wxEmptyString
); 
2796 // add a catalog to our linked list 
2797 bool wxLocale::AddCatalog(const wxString
& szDomain
, 
2798                           wxLanguage      msgIdLanguage
, 
2799                           const wxString
& msgIdCharset
) 
2802   wxMsgCatalog 
*pMsgCat 
= new wxMsgCatalog
; 
2804   if ( pMsgCat
->Load(m_strShort
, szDomain
, msgIdCharset
, m_bConvertEncoding
) ) { 
2805     // add it to the head of the list so that in GetString it will 
2806     // be searched before the catalogs added earlier 
2807     pMsgCat
->m_pNext 
= m_pMsgCat
; 
2808     m_pMsgCat 
= pMsgCat
; 
2813     // don't add it because it couldn't be loaded anyway 
2816     // It is OK to not load catalog if the msgid language and m_language match, 
2817     // in which case we can directly display the texts embedded in program's 
2819     if (m_language 
== msgIdLanguage
) 
2822     // If there's no exact match, we may still get partial match where the 
2823     // (basic) language is same, but the country differs. For example, it's 
2824     // permitted to use en_US strings from sources even if m_language is en_GB: 
2825     const wxLanguageInfo 
*msgIdLangInfo 
= GetLanguageInfo(msgIdLanguage
); 
2826     if ( msgIdLangInfo 
&& 
2827          msgIdLangInfo
->CanonicalName
.Mid(0, 2) == m_strShort
.Mid(0, 2) ) 
2836 // ---------------------------------------------------------------------------- 
2837 // accessors for locale-dependent data 
2838 // ---------------------------------------------------------------------------- 
2843 wxString 
wxLocale::GetInfo(wxLocaleInfo index
, wxLocaleCategory 
WXUNUSED(cat
)) 
2848     buffer
[0] = wxT('\0'); 
2851         case wxLOCALE_DECIMAL_POINT
: 
2852             count 
= ::GetLocaleInfo(LOCALE_USER_DEFAULT
, LOCALE_SDECIMAL
, buffer
, 256); 
2859         case wxSYS_LIST_SEPARATOR
: 
2860             count 
= ::GetLocaleInfo(LOCALE_USER_DEFAULT
, LOCALE_SLIST
, buffer
, 256); 
2866         case wxSYS_LEADING_ZERO
: // 0 means no leading zero, 1 means leading zero 
2867             count 
= ::GetLocaleInfo(LOCALE_USER_DEFAULT
, LOCALE_ILZERO
, buffer
, 256); 
2875             wxFAIL_MSG(wxT("Unknown System String !")); 
2883 wxString 
wxLocale::GetInfo(wxLocaleInfo index
, wxLocaleCategory cat
) 
2885     struct lconv 
*locale_info 
= localeconv(); 
2888         case wxLOCALE_CAT_NUMBER
: 
2891                 case wxLOCALE_THOUSANDS_SEP
: 
2892                     return wxString(locale_info
->thousands_sep
, 
2894                 case wxLOCALE_DECIMAL_POINT
: 
2895                     return wxString(locale_info
->decimal_point
, 
2898                     return wxEmptyString
; 
2900         case wxLOCALE_CAT_MONEY
: 
2903                 case wxLOCALE_THOUSANDS_SEP
: 
2904                     return wxString(locale_info
->mon_thousands_sep
, 
2906                 case wxLOCALE_DECIMAL_POINT
: 
2907                     return wxString(locale_info
->mon_decimal_point
, 
2910                     return wxEmptyString
; 
2913             return wxEmptyString
; 
2917 #endif // __WXMSW__/!__WXMSW__ 
2919 // ---------------------------------------------------------------------------- 
2920 // global functions and variables 
2921 // ---------------------------------------------------------------------------- 
2923 // retrieve/change current locale 
2924 // ------------------------------ 
2926 // the current locale object 
2927 static wxLocale 
*g_pLocale 
= NULL
; 
2929 wxLocale 
*wxGetLocale() 
2934 wxLocale 
*wxSetLocale(wxLocale 
*pLocale
) 
2936   wxLocale 
*pOld 
= g_pLocale
; 
2937   g_pLocale 
= pLocale
; 
2943 // ---------------------------------------------------------------------------- 
2944 // wxLocale module (for lazy destruction of languagesDB) 
2945 // ---------------------------------------------------------------------------- 
2947 class wxLocaleModule
: public wxModule
 
2949     DECLARE_DYNAMIC_CLASS(wxLocaleModule
) 
2952         bool OnInit() { return true; } 
2953         void OnExit() { wxLocale::DestroyLanguagesDB(); } 
2956 IMPLEMENT_DYNAMIC_CLASS(wxLocaleModule
, wxModule
) 
2960 // ---------------------------------------------------------------------------- 
2961 // default languages table & initialization 
2962 // ---------------------------------------------------------------------------- 
2966 // --- --- --- generated code begins here --- --- --- 
2968 // This table is generated by misc/languages/genlang.py 
2969 // When making changes, please put them into misc/languages/langtabl.txt 
2971 #if !defined(__WIN32__) || defined(__WXMICROWIN__) 
2973 #define SETWINLANG(info,lang,sublang) 
2977 #define SETWINLANG(info,lang,sublang) \ 
2978     info.WinLang = lang, info.WinSublang = sublang; 
2980 #ifndef LANG_AFRIKAANS 
2981 #define LANG_AFRIKAANS (0) 
2983 #ifndef LANG_ALBANIAN 
2984 #define LANG_ALBANIAN (0) 
2987 #define LANG_ARABIC (0) 
2989 #ifndef LANG_ARMENIAN 
2990 #define LANG_ARMENIAN (0) 
2992 #ifndef LANG_ASSAMESE 
2993 #define LANG_ASSAMESE (0) 
2996 #define LANG_AZERI (0) 
2999 #define LANG_BASQUE (0) 
3001 #ifndef LANG_BELARUSIAN 
3002 #define LANG_BELARUSIAN (0) 
3004 #ifndef LANG_BENGALI 
3005 #define LANG_BENGALI (0) 
3007 #ifndef LANG_BULGARIAN 
3008 #define LANG_BULGARIAN (0) 
3010 #ifndef LANG_CATALAN 
3011 #define LANG_CATALAN (0) 
3013 #ifndef LANG_CHINESE 
3014 #define LANG_CHINESE (0) 
3016 #ifndef LANG_CROATIAN 
3017 #define LANG_CROATIAN (0) 
3020 #define LANG_CZECH (0) 
3023 #define LANG_DANISH (0) 
3026 #define LANG_DUTCH (0) 
3028 #ifndef LANG_ENGLISH 
3029 #define LANG_ENGLISH (0) 
3031 #ifndef LANG_ESTONIAN 
3032 #define LANG_ESTONIAN (0) 
3034 #ifndef LANG_FAEROESE 
3035 #define LANG_FAEROESE (0) 
3038 #define LANG_FARSI (0) 
3040 #ifndef LANG_FINNISH 
3041 #define LANG_FINNISH (0) 
3044 #define LANG_FRENCH (0) 
3046 #ifndef LANG_GEORGIAN 
3047 #define LANG_GEORGIAN (0) 
3050 #define LANG_GERMAN (0) 
3053 #define LANG_GREEK (0) 
3055 #ifndef LANG_GUJARATI 
3056 #define LANG_GUJARATI (0) 
3059 #define LANG_HEBREW (0) 
3062 #define LANG_HINDI (0) 
3064 #ifndef LANG_HUNGARIAN 
3065 #define LANG_HUNGARIAN (0) 
3067 #ifndef LANG_ICELANDIC 
3068 #define LANG_ICELANDIC (0) 
3070 #ifndef LANG_INDONESIAN 
3071 #define LANG_INDONESIAN (0) 
3073 #ifndef LANG_ITALIAN 
3074 #define LANG_ITALIAN (0) 
3076 #ifndef LANG_JAPANESE 
3077 #define LANG_JAPANESE (0) 
3079 #ifndef LANG_KANNADA 
3080 #define LANG_KANNADA (0) 
3082 #ifndef LANG_KASHMIRI 
3083 #define LANG_KASHMIRI (0) 
3086 #define LANG_KAZAK (0) 
3088 #ifndef LANG_KONKANI 
3089 #define LANG_KONKANI (0) 
3092 #define LANG_KOREAN (0) 
3094 #ifndef LANG_LATVIAN 
3095 #define LANG_LATVIAN (0) 
3097 #ifndef LANG_LITHUANIAN 
3098 #define LANG_LITHUANIAN (0) 
3100 #ifndef LANG_MACEDONIAN 
3101 #define LANG_MACEDONIAN (0) 
3104 #define LANG_MALAY (0) 
3106 #ifndef LANG_MALAYALAM 
3107 #define LANG_MALAYALAM (0) 
3109 #ifndef LANG_MANIPURI 
3110 #define LANG_MANIPURI (0) 
3112 #ifndef LANG_MARATHI 
3113 #define LANG_MARATHI (0) 
3116 #define LANG_NEPALI (0) 
3118 #ifndef LANG_NORWEGIAN 
3119 #define LANG_NORWEGIAN (0) 
3122 #define LANG_ORIYA (0) 
3125 #define LANG_POLISH (0) 
3127 #ifndef LANG_PORTUGUESE 
3128 #define LANG_PORTUGUESE (0) 
3130 #ifndef LANG_PUNJABI 
3131 #define LANG_PUNJABI (0) 
3133 #ifndef LANG_ROMANIAN 
3134 #define LANG_ROMANIAN (0) 
3136 #ifndef LANG_RUSSIAN 
3137 #define LANG_RUSSIAN (0) 
3139 #ifndef LANG_SANSKRIT 
3140 #define LANG_SANSKRIT (0) 
3142 #ifndef LANG_SERBIAN 
3143 #define LANG_SERBIAN (0) 
3146 #define LANG_SINDHI (0) 
3149 #define LANG_SLOVAK (0) 
3151 #ifndef LANG_SLOVENIAN 
3152 #define LANG_SLOVENIAN (0) 
3154 #ifndef LANG_SPANISH 
3155 #define LANG_SPANISH (0) 
3157 #ifndef LANG_SWAHILI 
3158 #define LANG_SWAHILI (0) 
3160 #ifndef LANG_SWEDISH 
3161 #define LANG_SWEDISH (0) 
3164 #define LANG_TAMIL (0) 
3167 #define LANG_TATAR (0) 
3170 #define LANG_TELUGU (0) 
3173 #define LANG_THAI (0) 
3175 #ifndef LANG_TURKISH 
3176 #define LANG_TURKISH (0) 
3178 #ifndef LANG_UKRAINIAN 
3179 #define LANG_UKRAINIAN (0) 
3182 #define LANG_URDU (0) 
3185 #define LANG_UZBEK (0) 
3187 #ifndef LANG_VIETNAMESE 
3188 #define LANG_VIETNAMESE (0) 
3190 #ifndef SUBLANG_ARABIC_ALGERIA 
3191 #define SUBLANG_ARABIC_ALGERIA SUBLANG_DEFAULT 
3193 #ifndef SUBLANG_ARABIC_BAHRAIN 
3194 #define SUBLANG_ARABIC_BAHRAIN SUBLANG_DEFAULT 
3196 #ifndef SUBLANG_ARABIC_EGYPT 
3197 #define SUBLANG_ARABIC_EGYPT SUBLANG_DEFAULT 
3199 #ifndef SUBLANG_ARABIC_IRAQ 
3200 #define SUBLANG_ARABIC_IRAQ SUBLANG_DEFAULT 
3202 #ifndef SUBLANG_ARABIC_JORDAN 
3203 #define SUBLANG_ARABIC_JORDAN SUBLANG_DEFAULT 
3205 #ifndef SUBLANG_ARABIC_KUWAIT 
3206 #define SUBLANG_ARABIC_KUWAIT SUBLANG_DEFAULT 
3208 #ifndef SUBLANG_ARABIC_LEBANON 
3209 #define SUBLANG_ARABIC_LEBANON SUBLANG_DEFAULT 
3211 #ifndef SUBLANG_ARABIC_LIBYA 
3212 #define SUBLANG_ARABIC_LIBYA SUBLANG_DEFAULT 
3214 #ifndef SUBLANG_ARABIC_MOROCCO 
3215 #define SUBLANG_ARABIC_MOROCCO SUBLANG_DEFAULT 
3217 #ifndef SUBLANG_ARABIC_OMAN 
3218 #define SUBLANG_ARABIC_OMAN SUBLANG_DEFAULT 
3220 #ifndef SUBLANG_ARABIC_QATAR 
3221 #define SUBLANG_ARABIC_QATAR SUBLANG_DEFAULT 
3223 #ifndef SUBLANG_ARABIC_SAUDI_ARABIA 
3224 #define SUBLANG_ARABIC_SAUDI_ARABIA SUBLANG_DEFAULT 
3226 #ifndef SUBLANG_ARABIC_SYRIA 
3227 #define SUBLANG_ARABIC_SYRIA SUBLANG_DEFAULT 
3229 #ifndef SUBLANG_ARABIC_TUNISIA 
3230 #define SUBLANG_ARABIC_TUNISIA SUBLANG_DEFAULT 
3232 #ifndef SUBLANG_ARABIC_UAE 
3233 #define SUBLANG_ARABIC_UAE SUBLANG_DEFAULT 
3235 #ifndef SUBLANG_ARABIC_YEMEN 
3236 #define SUBLANG_ARABIC_YEMEN SUBLANG_DEFAULT 
3238 #ifndef SUBLANG_AZERI_CYRILLIC 
3239 #define SUBLANG_AZERI_CYRILLIC SUBLANG_DEFAULT 
3241 #ifndef SUBLANG_AZERI_LATIN 
3242 #define SUBLANG_AZERI_LATIN SUBLANG_DEFAULT 
3244 #ifndef SUBLANG_CHINESE_SIMPLIFIED 
3245 #define SUBLANG_CHINESE_SIMPLIFIED SUBLANG_DEFAULT 
3247 #ifndef SUBLANG_CHINESE_TRADITIONAL 
3248 #define SUBLANG_CHINESE_TRADITIONAL SUBLANG_DEFAULT 
3250 #ifndef SUBLANG_CHINESE_HONGKONG 
3251 #define SUBLANG_CHINESE_HONGKONG SUBLANG_DEFAULT 
3253 #ifndef SUBLANG_CHINESE_MACAU 
3254 #define SUBLANG_CHINESE_MACAU SUBLANG_DEFAULT 
3256 #ifndef SUBLANG_CHINESE_SINGAPORE 
3257 #define SUBLANG_CHINESE_SINGAPORE SUBLANG_DEFAULT 
3259 #ifndef SUBLANG_DUTCH 
3260 #define SUBLANG_DUTCH SUBLANG_DEFAULT 
3262 #ifndef SUBLANG_DUTCH_BELGIAN 
3263 #define SUBLANG_DUTCH_BELGIAN SUBLANG_DEFAULT 
3265 #ifndef SUBLANG_ENGLISH_UK 
3266 #define SUBLANG_ENGLISH_UK SUBLANG_DEFAULT 
3268 #ifndef SUBLANG_ENGLISH_US 
3269 #define SUBLANG_ENGLISH_US SUBLANG_DEFAULT 
3271 #ifndef SUBLANG_ENGLISH_AUS 
3272 #define SUBLANG_ENGLISH_AUS SUBLANG_DEFAULT 
3274 #ifndef SUBLANG_ENGLISH_BELIZE 
3275 #define SUBLANG_ENGLISH_BELIZE SUBLANG_DEFAULT 
3277 #ifndef SUBLANG_ENGLISH_CAN 
3278 #define SUBLANG_ENGLISH_CAN SUBLANG_DEFAULT 
3280 #ifndef SUBLANG_ENGLISH_CARIBBEAN 
3281 #define SUBLANG_ENGLISH_CARIBBEAN SUBLANG_DEFAULT 
3283 #ifndef SUBLANG_ENGLISH_EIRE 
3284 #define SUBLANG_ENGLISH_EIRE SUBLANG_DEFAULT 
3286 #ifndef SUBLANG_ENGLISH_JAMAICA 
3287 #define SUBLANG_ENGLISH_JAMAICA SUBLANG_DEFAULT 
3289 #ifndef SUBLANG_ENGLISH_NZ 
3290 #define SUBLANG_ENGLISH_NZ SUBLANG_DEFAULT 
3292 #ifndef SUBLANG_ENGLISH_PHILIPPINES 
3293 #define SUBLANG_ENGLISH_PHILIPPINES SUBLANG_DEFAULT 
3295 #ifndef SUBLANG_ENGLISH_SOUTH_AFRICA 
3296 #define SUBLANG_ENGLISH_SOUTH_AFRICA SUBLANG_DEFAULT 
3298 #ifndef SUBLANG_ENGLISH_TRINIDAD 
3299 #define SUBLANG_ENGLISH_TRINIDAD SUBLANG_DEFAULT 
3301 #ifndef SUBLANG_ENGLISH_ZIMBABWE 
3302 #define SUBLANG_ENGLISH_ZIMBABWE SUBLANG_DEFAULT 
3304 #ifndef SUBLANG_FRENCH 
3305 #define SUBLANG_FRENCH SUBLANG_DEFAULT 
3307 #ifndef SUBLANG_FRENCH_BELGIAN 
3308 #define SUBLANG_FRENCH_BELGIAN SUBLANG_DEFAULT 
3310 #ifndef SUBLANG_FRENCH_CANADIAN 
3311 #define SUBLANG_FRENCH_CANADIAN SUBLANG_DEFAULT 
3313 #ifndef SUBLANG_FRENCH_LUXEMBOURG 
3314 #define SUBLANG_FRENCH_LUXEMBOURG SUBLANG_DEFAULT 
3316 #ifndef SUBLANG_FRENCH_MONACO 
3317 #define SUBLANG_FRENCH_MONACO SUBLANG_DEFAULT 
3319 #ifndef SUBLANG_FRENCH_SWISS 
3320 #define SUBLANG_FRENCH_SWISS SUBLANG_DEFAULT 
3322 #ifndef SUBLANG_GERMAN 
3323 #define SUBLANG_GERMAN SUBLANG_DEFAULT 
3325 #ifndef SUBLANG_GERMAN_AUSTRIAN 
3326 #define SUBLANG_GERMAN_AUSTRIAN SUBLANG_DEFAULT 
3328 #ifndef SUBLANG_GERMAN_LIECHTENSTEIN 
3329 #define SUBLANG_GERMAN_LIECHTENSTEIN SUBLANG_DEFAULT 
3331 #ifndef SUBLANG_GERMAN_LUXEMBOURG 
3332 #define SUBLANG_GERMAN_LUXEMBOURG SUBLANG_DEFAULT 
3334 #ifndef SUBLANG_GERMAN_SWISS 
3335 #define SUBLANG_GERMAN_SWISS SUBLANG_DEFAULT 
3337 #ifndef SUBLANG_ITALIAN 
3338 #define SUBLANG_ITALIAN SUBLANG_DEFAULT 
3340 #ifndef SUBLANG_ITALIAN_SWISS 
3341 #define SUBLANG_ITALIAN_SWISS SUBLANG_DEFAULT 
3343 #ifndef SUBLANG_KASHMIRI_INDIA 
3344 #define SUBLANG_KASHMIRI_INDIA SUBLANG_DEFAULT 
3346 #ifndef SUBLANG_KOREAN 
3347 #define SUBLANG_KOREAN SUBLANG_DEFAULT 
3349 #ifndef SUBLANG_LITHUANIAN 
3350 #define SUBLANG_LITHUANIAN SUBLANG_DEFAULT 
3352 #ifndef SUBLANG_MALAY_BRUNEI_DARUSSALAM 
3353 #define SUBLANG_MALAY_BRUNEI_DARUSSALAM SUBLANG_DEFAULT 
3355 #ifndef SUBLANG_MALAY_MALAYSIA 
3356 #define SUBLANG_MALAY_MALAYSIA SUBLANG_DEFAULT 
3358 #ifndef SUBLANG_NEPALI_INDIA 
3359 #define SUBLANG_NEPALI_INDIA SUBLANG_DEFAULT 
3361 #ifndef SUBLANG_NORWEGIAN_BOKMAL 
3362 #define SUBLANG_NORWEGIAN_BOKMAL SUBLANG_DEFAULT 
3364 #ifndef SUBLANG_NORWEGIAN_NYNORSK 
3365 #define SUBLANG_NORWEGIAN_NYNORSK SUBLANG_DEFAULT 
3367 #ifndef SUBLANG_PORTUGUESE 
3368 #define SUBLANG_PORTUGUESE SUBLANG_DEFAULT 
3370 #ifndef SUBLANG_PORTUGUESE_BRAZILIAN 
3371 #define SUBLANG_PORTUGUESE_BRAZILIAN SUBLANG_DEFAULT 
3373 #ifndef SUBLANG_SERBIAN_CYRILLIC 
3374 #define SUBLANG_SERBIAN_CYRILLIC SUBLANG_DEFAULT 
3376 #ifndef SUBLANG_SERBIAN_LATIN 
3377 #define SUBLANG_SERBIAN_LATIN SUBLANG_DEFAULT 
3379 #ifndef SUBLANG_SPANISH 
3380 #define SUBLANG_SPANISH SUBLANG_DEFAULT 
3382 #ifndef SUBLANG_SPANISH_ARGENTINA 
3383 #define SUBLANG_SPANISH_ARGENTINA SUBLANG_DEFAULT 
3385 #ifndef SUBLANG_SPANISH_BOLIVIA 
3386 #define SUBLANG_SPANISH_BOLIVIA SUBLANG_DEFAULT 
3388 #ifndef SUBLANG_SPANISH_CHILE 
3389 #define SUBLANG_SPANISH_CHILE SUBLANG_DEFAULT 
3391 #ifndef SUBLANG_SPANISH_COLOMBIA 
3392 #define SUBLANG_SPANISH_COLOMBIA SUBLANG_DEFAULT 
3394 #ifndef SUBLANG_SPANISH_COSTA_RICA 
3395 #define SUBLANG_SPANISH_COSTA_RICA SUBLANG_DEFAULT 
3397 #ifndef SUBLANG_SPANISH_DOMINICAN_REPUBLIC 
3398 #define SUBLANG_SPANISH_DOMINICAN_REPUBLIC SUBLANG_DEFAULT 
3400 #ifndef SUBLANG_SPANISH_ECUADOR 
3401 #define SUBLANG_SPANISH_ECUADOR SUBLANG_DEFAULT 
3403 #ifndef SUBLANG_SPANISH_EL_SALVADOR 
3404 #define SUBLANG_SPANISH_EL_SALVADOR SUBLANG_DEFAULT 
3406 #ifndef SUBLANG_SPANISH_GUATEMALA 
3407 #define SUBLANG_SPANISH_GUATEMALA SUBLANG_DEFAULT 
3409 #ifndef SUBLANG_SPANISH_HONDURAS 
3410 #define SUBLANG_SPANISH_HONDURAS SUBLANG_DEFAULT 
3412 #ifndef SUBLANG_SPANISH_MEXICAN 
3413 #define SUBLANG_SPANISH_MEXICAN SUBLANG_DEFAULT 
3415 #ifndef SUBLANG_SPANISH_MODERN 
3416 #define SUBLANG_SPANISH_MODERN SUBLANG_DEFAULT 
3418 #ifndef SUBLANG_SPANISH_NICARAGUA 
3419 #define SUBLANG_SPANISH_NICARAGUA SUBLANG_DEFAULT 
3421 #ifndef SUBLANG_SPANISH_PANAMA 
3422 #define SUBLANG_SPANISH_PANAMA SUBLANG_DEFAULT 
3424 #ifndef SUBLANG_SPANISH_PARAGUAY 
3425 #define SUBLANG_SPANISH_PARAGUAY SUBLANG_DEFAULT 
3427 #ifndef SUBLANG_SPANISH_PERU 
3428 #define SUBLANG_SPANISH_PERU SUBLANG_DEFAULT 
3430 #ifndef SUBLANG_SPANISH_PUERTO_RICO 
3431 #define SUBLANG_SPANISH_PUERTO_RICO SUBLANG_DEFAULT 
3433 #ifndef SUBLANG_SPANISH_URUGUAY 
3434 #define SUBLANG_SPANISH_URUGUAY SUBLANG_DEFAULT 
3436 #ifndef SUBLANG_SPANISH_VENEZUELA 
3437 #define SUBLANG_SPANISH_VENEZUELA SUBLANG_DEFAULT 
3439 #ifndef SUBLANG_SWEDISH 
3440 #define SUBLANG_SWEDISH SUBLANG_DEFAULT 
3442 #ifndef SUBLANG_SWEDISH_FINLAND 
3443 #define SUBLANG_SWEDISH_FINLAND SUBLANG_DEFAULT 
3445 #ifndef SUBLANG_URDU_INDIA 
3446 #define SUBLANG_URDU_INDIA SUBLANG_DEFAULT 
3448 #ifndef SUBLANG_URDU_PAKISTAN 
3449 #define SUBLANG_URDU_PAKISTAN SUBLANG_DEFAULT 
3451 #ifndef SUBLANG_UZBEK_CYRILLIC 
3452 #define SUBLANG_UZBEK_CYRILLIC SUBLANG_DEFAULT 
3454 #ifndef SUBLANG_UZBEK_LATIN 
3455 #define SUBLANG_UZBEK_LATIN SUBLANG_DEFAULT 
3461 #define LNG(wxlang, canonical, winlang, winsublang, layout, desc) \ 
3462     info.Language = wxlang;                               \ 
3463     info.CanonicalName = wxT(canonical);                  \ 
3464     info.LayoutDirection = layout;                        \ 
3465     info.Description = wxT(desc);                         \ 
3466     SETWINLANG(info, winlang, winsublang)                 \ 
3469 void wxLocale::InitLanguagesDB() 
3471    wxLanguageInfo info
; 
3472    wxStringTokenizer tkn
; 
3474    LNG(wxLANGUAGE_ABKHAZIAN
,                  "ab"   , 0              , 0                                 , wxLayout_LeftToRight
, "Abkhazian") 
3475    LNG(wxLANGUAGE_AFAR
,                       "aa"   , 0              , 0                                 , wxLayout_LeftToRight
, "Afar") 
3476    LNG(wxLANGUAGE_AFRIKAANS
,                  "af_ZA", LANG_AFRIKAANS 
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Afrikaans") 
3477    LNG(wxLANGUAGE_ALBANIAN
,                   "sq_AL", LANG_ALBANIAN  
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Albanian") 
3478    LNG(wxLANGUAGE_AMHARIC
,                    "am"   , 0              , 0                                 , wxLayout_LeftToRight
, "Amharic") 
3479    LNG(wxLANGUAGE_ARABIC
,                     "ar"   , LANG_ARABIC    
, SUBLANG_DEFAULT                   
, wxLayout_RightToLeft
, "Arabic") 
3480    LNG(wxLANGUAGE_ARABIC_ALGERIA
,             "ar_DZ", LANG_ARABIC    
, SUBLANG_ARABIC_ALGERIA            
, wxLayout_RightToLeft
, "Arabic (Algeria)") 
3481    LNG(wxLANGUAGE_ARABIC_BAHRAIN
,             "ar_BH", LANG_ARABIC    
, SUBLANG_ARABIC_BAHRAIN            
, wxLayout_RightToLeft
, "Arabic (Bahrain)") 
3482    LNG(wxLANGUAGE_ARABIC_EGYPT
,               "ar_EG", LANG_ARABIC    
, SUBLANG_ARABIC_EGYPT              
, wxLayout_RightToLeft
, "Arabic (Egypt)") 
3483    LNG(wxLANGUAGE_ARABIC_IRAQ
,                "ar_IQ", LANG_ARABIC    
, SUBLANG_ARABIC_IRAQ               
, wxLayout_RightToLeft
, "Arabic (Iraq)") 
3484    LNG(wxLANGUAGE_ARABIC_JORDAN
,              "ar_JO", LANG_ARABIC    
, SUBLANG_ARABIC_JORDAN             
, wxLayout_RightToLeft
, "Arabic (Jordan)") 
3485    LNG(wxLANGUAGE_ARABIC_KUWAIT
,              "ar_KW", LANG_ARABIC    
, SUBLANG_ARABIC_KUWAIT             
, wxLayout_RightToLeft
, "Arabic (Kuwait)") 
3486    LNG(wxLANGUAGE_ARABIC_LEBANON
,             "ar_LB", LANG_ARABIC    
, SUBLANG_ARABIC_LEBANON            
, wxLayout_RightToLeft
, "Arabic (Lebanon)") 
3487    LNG(wxLANGUAGE_ARABIC_LIBYA
,               "ar_LY", LANG_ARABIC    
, SUBLANG_ARABIC_LIBYA              
, wxLayout_RightToLeft
, "Arabic (Libya)") 
3488    LNG(wxLANGUAGE_ARABIC_MOROCCO
,             "ar_MA", LANG_ARABIC    
, SUBLANG_ARABIC_MOROCCO            
, wxLayout_RightToLeft
, "Arabic (Morocco)") 
3489    LNG(wxLANGUAGE_ARABIC_OMAN
,                "ar_OM", LANG_ARABIC    
, SUBLANG_ARABIC_OMAN               
, wxLayout_RightToLeft
, "Arabic (Oman)") 
3490    LNG(wxLANGUAGE_ARABIC_QATAR
,               "ar_QA", LANG_ARABIC    
, SUBLANG_ARABIC_QATAR              
, wxLayout_RightToLeft
, "Arabic (Qatar)") 
3491    LNG(wxLANGUAGE_ARABIC_SAUDI_ARABIA
,        "ar_SA", LANG_ARABIC    
, SUBLANG_ARABIC_SAUDI_ARABIA       
, wxLayout_RightToLeft
, "Arabic (Saudi Arabia)") 
3492    LNG(wxLANGUAGE_ARABIC_SUDAN
,               "ar_SD", 0              , 0                                 , wxLayout_RightToLeft
, "Arabic (Sudan)") 
3493    LNG(wxLANGUAGE_ARABIC_SYRIA
,               "ar_SY", LANG_ARABIC    
, SUBLANG_ARABIC_SYRIA              
, wxLayout_RightToLeft
, "Arabic (Syria)") 
3494    LNG(wxLANGUAGE_ARABIC_TUNISIA
,             "ar_TN", LANG_ARABIC    
, SUBLANG_ARABIC_TUNISIA            
, wxLayout_RightToLeft
, "Arabic (Tunisia)") 
3495    LNG(wxLANGUAGE_ARABIC_UAE
,                 "ar_AE", LANG_ARABIC    
, SUBLANG_ARABIC_UAE                
, wxLayout_RightToLeft
, "Arabic (Uae)") 
3496    LNG(wxLANGUAGE_ARABIC_YEMEN
,               "ar_YE", LANG_ARABIC    
, SUBLANG_ARABIC_YEMEN              
, wxLayout_RightToLeft
, "Arabic (Yemen)") 
3497    LNG(wxLANGUAGE_ARMENIAN
,                   "hy"   , LANG_ARMENIAN  
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Armenian") 
3498    LNG(wxLANGUAGE_ASSAMESE
,                   "as"   , LANG_ASSAMESE  
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Assamese") 
3499    LNG(wxLANGUAGE_AYMARA
,                     "ay"   , 0              , 0                                 , wxLayout_LeftToRight
, "Aymara") 
3500    LNG(wxLANGUAGE_AZERI
,                      "az"   , LANG_AZERI     
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Azeri") 
3501    LNG(wxLANGUAGE_AZERI_CYRILLIC
,             "az"   , LANG_AZERI     
, SUBLANG_AZERI_CYRILLIC            
, wxLayout_LeftToRight
, "Azeri (Cyrillic)") 
3502    LNG(wxLANGUAGE_AZERI_LATIN
,                "az"   , LANG_AZERI     
, SUBLANG_AZERI_LATIN               
, wxLayout_LeftToRight
, "Azeri (Latin)") 
3503    LNG(wxLANGUAGE_BASHKIR
,                    "ba"   , 0              , 0                                 , wxLayout_LeftToRight
, "Bashkir") 
3504    LNG(wxLANGUAGE_BASQUE
,                     "eu_ES", LANG_BASQUE    
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Basque") 
3505    LNG(wxLANGUAGE_BELARUSIAN
,                 "be_BY", LANG_BELARUSIAN
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Belarusian") 
3506    LNG(wxLANGUAGE_BENGALI
,                    "bn"   , LANG_BENGALI   
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Bengali") 
3507    LNG(wxLANGUAGE_BHUTANI
,                    "dz"   , 0              , 0                                 , wxLayout_LeftToRight
, "Bhutani") 
3508    LNG(wxLANGUAGE_BIHARI
,                     "bh"   , 0              , 0                                 , wxLayout_LeftToRight
, "Bihari") 
3509    LNG(wxLANGUAGE_BISLAMA
,                    "bi"   , 0              , 0                                 , wxLayout_LeftToRight
, "Bislama") 
3510    LNG(wxLANGUAGE_BRETON
,                     "br"   , 0              , 0                                 , wxLayout_LeftToRight
, "Breton") 
3511    LNG(wxLANGUAGE_BULGARIAN
,                  "bg_BG", LANG_BULGARIAN 
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Bulgarian") 
3512    LNG(wxLANGUAGE_BURMESE
,                    "my"   , 0              , 0                                 , wxLayout_LeftToRight
, "Burmese") 
3513    LNG(wxLANGUAGE_CAMBODIAN
,                  "km"   , 0              , 0                                 , wxLayout_LeftToRight
, "Cambodian") 
3514    LNG(wxLANGUAGE_CATALAN
,                    "ca_ES", LANG_CATALAN   
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Catalan") 
3515    LNG(wxLANGUAGE_CHINESE
,                    "zh_TW", LANG_CHINESE   
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Chinese") 
3516    LNG(wxLANGUAGE_CHINESE_SIMPLIFIED
,         "zh_CN", LANG_CHINESE   
, SUBLANG_CHINESE_SIMPLIFIED        
, wxLayout_LeftToRight
, "Chinese (Simplified)") 
3517    LNG(wxLANGUAGE_CHINESE_TRADITIONAL
,        "zh_TW", LANG_CHINESE   
, SUBLANG_CHINESE_TRADITIONAL       
, wxLayout_LeftToRight
, "Chinese (Traditional)") 
3518    LNG(wxLANGUAGE_CHINESE_HONGKONG
,           "zh_HK", LANG_CHINESE   
, SUBLANG_CHINESE_HONGKONG          
, wxLayout_LeftToRight
, "Chinese (Hongkong)") 
3519    LNG(wxLANGUAGE_CHINESE_MACAU
,              "zh_MO", LANG_CHINESE   
, SUBLANG_CHINESE_MACAU             
, wxLayout_LeftToRight
, "Chinese (Macau)") 
3520    LNG(wxLANGUAGE_CHINESE_SINGAPORE
,          "zh_SG", LANG_CHINESE   
, SUBLANG_CHINESE_SINGAPORE         
, wxLayout_LeftToRight
, "Chinese (Singapore)") 
3521    LNG(wxLANGUAGE_CHINESE_TAIWAN
,             "zh_TW", LANG_CHINESE   
, SUBLANG_CHINESE_TRADITIONAL       
, wxLayout_LeftToRight
, "Chinese (Taiwan)") 
3522    LNG(wxLANGUAGE_CORSICAN
,                   "co"   , 0              , 0                                 , wxLayout_LeftToRight
, "Corsican") 
3523    LNG(wxLANGUAGE_CROATIAN
,                   "hr_HR", LANG_CROATIAN  
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Croatian") 
3524    LNG(wxLANGUAGE_CZECH
,                      "cs_CZ", LANG_CZECH     
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Czech") 
3525    LNG(wxLANGUAGE_DANISH
,                     "da_DK", LANG_DANISH    
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Danish") 
3526    LNG(wxLANGUAGE_DUTCH
,                      "nl_NL", LANG_DUTCH     
, SUBLANG_DUTCH                     
, wxLayout_LeftToRight
, "Dutch") 
3527    LNG(wxLANGUAGE_DUTCH_BELGIAN
,              "nl_BE", LANG_DUTCH     
, SUBLANG_DUTCH_BELGIAN             
, wxLayout_LeftToRight
, "Dutch (Belgian)") 
3528    LNG(wxLANGUAGE_ENGLISH
,                    "en_GB", LANG_ENGLISH   
, SUBLANG_ENGLISH_UK                
, wxLayout_LeftToRight
, "English") 
3529    LNG(wxLANGUAGE_ENGLISH_UK
,                 "en_GB", LANG_ENGLISH   
, SUBLANG_ENGLISH_UK                
, wxLayout_LeftToRight
, "English (U.K.)") 
3530    LNG(wxLANGUAGE_ENGLISH_US
,                 "en_US", LANG_ENGLISH   
, SUBLANG_ENGLISH_US                
, wxLayout_LeftToRight
, "English (U.S.)") 
3531    LNG(wxLANGUAGE_ENGLISH_AUSTRALIA
,          "en_AU", LANG_ENGLISH   
, SUBLANG_ENGLISH_AUS               
, wxLayout_LeftToRight
, "English (Australia)") 
3532    LNG(wxLANGUAGE_ENGLISH_BELIZE
,             "en_BZ", LANG_ENGLISH   
, SUBLANG_ENGLISH_BELIZE            
, wxLayout_LeftToRight
, "English (Belize)") 
3533    LNG(wxLANGUAGE_ENGLISH_BOTSWANA
,           "en_BW", 0              , 0                                 , wxLayout_LeftToRight
, "English (Botswana)") 
3534    LNG(wxLANGUAGE_ENGLISH_CANADA
,             "en_CA", LANG_ENGLISH   
, SUBLANG_ENGLISH_CAN               
, wxLayout_LeftToRight
, "English (Canada)") 
3535    LNG(wxLANGUAGE_ENGLISH_CARIBBEAN
,          "en_CB", LANG_ENGLISH   
, SUBLANG_ENGLISH_CARIBBEAN         
, wxLayout_LeftToRight
, "English (Caribbean)") 
3536    LNG(wxLANGUAGE_ENGLISH_DENMARK
,            "en_DK", 0              , 0                                 , wxLayout_LeftToRight
, "English (Denmark)") 
3537    LNG(wxLANGUAGE_ENGLISH_EIRE
,               "en_IE", LANG_ENGLISH   
, SUBLANG_ENGLISH_EIRE              
, wxLayout_LeftToRight
, "English (Eire)") 
3538    LNG(wxLANGUAGE_ENGLISH_JAMAICA
,            "en_JM", LANG_ENGLISH   
, SUBLANG_ENGLISH_JAMAICA           
, wxLayout_LeftToRight
, "English (Jamaica)") 
3539    LNG(wxLANGUAGE_ENGLISH_NEW_ZEALAND
,        "en_NZ", LANG_ENGLISH   
, SUBLANG_ENGLISH_NZ                
, wxLayout_LeftToRight
, "English (New Zealand)") 
3540    LNG(wxLANGUAGE_ENGLISH_PHILIPPINES
,        "en_PH", LANG_ENGLISH   
, SUBLANG_ENGLISH_PHILIPPINES       
, wxLayout_LeftToRight
, "English (Philippines)") 
3541    LNG(wxLANGUAGE_ENGLISH_SOUTH_AFRICA
,       "en_ZA", LANG_ENGLISH   
, SUBLANG_ENGLISH_SOUTH_AFRICA      
, wxLayout_LeftToRight
, "English (South Africa)") 
3542    LNG(wxLANGUAGE_ENGLISH_TRINIDAD
,           "en_TT", LANG_ENGLISH   
, SUBLANG_ENGLISH_TRINIDAD          
, wxLayout_LeftToRight
, "English (Trinidad)") 
3543    LNG(wxLANGUAGE_ENGLISH_ZIMBABWE
,           "en_ZW", LANG_ENGLISH   
, SUBLANG_ENGLISH_ZIMBABWE          
, wxLayout_LeftToRight
, "English (Zimbabwe)") 
3544    LNG(wxLANGUAGE_ESPERANTO
,                  "eo"   , 0              , 0                                 , wxLayout_LeftToRight
, "Esperanto") 
3545    LNG(wxLANGUAGE_ESTONIAN
,                   "et_EE", LANG_ESTONIAN  
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Estonian") 
3546    LNG(wxLANGUAGE_FAEROESE
,                   "fo_FO", LANG_FAEROESE  
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Faeroese") 
3547    LNG(wxLANGUAGE_FARSI
,                      "fa_IR", LANG_FARSI     
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Farsi") 
3548    LNG(wxLANGUAGE_FIJI
,                       "fj"   , 0              , 0                                 , wxLayout_LeftToRight
, "Fiji") 
3549    LNG(wxLANGUAGE_FINNISH
,                    "fi_FI", LANG_FINNISH   
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Finnish") 
3550    LNG(wxLANGUAGE_FRENCH
,                     "fr_FR", LANG_FRENCH    
, SUBLANG_FRENCH                    
, wxLayout_LeftToRight
, "French") 
3551    LNG(wxLANGUAGE_FRENCH_BELGIAN
,             "fr_BE", LANG_FRENCH    
, SUBLANG_FRENCH_BELGIAN            
, wxLayout_LeftToRight
, "French (Belgian)") 
3552    LNG(wxLANGUAGE_FRENCH_CANADIAN
,            "fr_CA", LANG_FRENCH    
, SUBLANG_FRENCH_CANADIAN           
, wxLayout_LeftToRight
, "French (Canadian)") 
3553    LNG(wxLANGUAGE_FRENCH_LUXEMBOURG
,          "fr_LU", LANG_FRENCH    
, SUBLANG_FRENCH_LUXEMBOURG         
, wxLayout_LeftToRight
, "French (Luxembourg)") 
3554    LNG(wxLANGUAGE_FRENCH_MONACO
,              "fr_MC", LANG_FRENCH    
, SUBLANG_FRENCH_MONACO             
, wxLayout_LeftToRight
, "French (Monaco)") 
3555    LNG(wxLANGUAGE_FRENCH_SWISS
,               "fr_CH", LANG_FRENCH    
, SUBLANG_FRENCH_SWISS              
, wxLayout_LeftToRight
, "French (Swiss)") 
3556    LNG(wxLANGUAGE_FRISIAN
,                    "fy"   , 0              , 0                                 , wxLayout_LeftToRight
, "Frisian") 
3557    LNG(wxLANGUAGE_GALICIAN
,                   "gl_ES", 0              , 0                                 , wxLayout_LeftToRight
, "Galician") 
3558    LNG(wxLANGUAGE_GEORGIAN
,                   "ka"   , LANG_GEORGIAN  
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Georgian") 
3559    LNG(wxLANGUAGE_GERMAN
,                     "de_DE", LANG_GERMAN    
, SUBLANG_GERMAN                    
, wxLayout_LeftToRight
, "German") 
3560    LNG(wxLANGUAGE_GERMAN_AUSTRIAN
,            "de_AT", LANG_GERMAN    
, SUBLANG_GERMAN_AUSTRIAN           
, wxLayout_LeftToRight
, "German (Austrian)") 
3561    LNG(wxLANGUAGE_GERMAN_BELGIUM
,             "de_BE", 0              , 0                                 , wxLayout_LeftToRight
, "German (Belgium)") 
3562    LNG(wxLANGUAGE_GERMAN_LIECHTENSTEIN
,       "de_LI", LANG_GERMAN    
, SUBLANG_GERMAN_LIECHTENSTEIN      
, wxLayout_LeftToRight
, "German (Liechtenstein)") 
3563    LNG(wxLANGUAGE_GERMAN_LUXEMBOURG
,          "de_LU", LANG_GERMAN    
, SUBLANG_GERMAN_LUXEMBOURG         
, wxLayout_LeftToRight
, "German (Luxembourg)") 
3564    LNG(wxLANGUAGE_GERMAN_SWISS
,               "de_CH", LANG_GERMAN    
, SUBLANG_GERMAN_SWISS              
, wxLayout_LeftToRight
, "German (Swiss)") 
3565    LNG(wxLANGUAGE_GREEK
,                      "el_GR", LANG_GREEK     
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Greek") 
3566    LNG(wxLANGUAGE_GREENLANDIC
,                "kl_GL", 0              , 0                                 , wxLayout_LeftToRight
, "Greenlandic") 
3567    LNG(wxLANGUAGE_GUARANI
,                    "gn"   , 0              , 0                                 , wxLayout_LeftToRight
, "Guarani") 
3568    LNG(wxLANGUAGE_GUJARATI
,                   "gu"   , LANG_GUJARATI  
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Gujarati") 
3569    LNG(wxLANGUAGE_HAUSA
,                      "ha"   , 0              , 0                                 , wxLayout_LeftToRight
, "Hausa") 
3570    LNG(wxLANGUAGE_HEBREW
,                     "he_IL", LANG_HEBREW    
, SUBLANG_DEFAULT                   
, wxLayout_RightToLeft
, "Hebrew") 
3571    LNG(wxLANGUAGE_HINDI
,                      "hi_IN", LANG_HINDI     
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Hindi") 
3572    LNG(wxLANGUAGE_HUNGARIAN
,                  "hu_HU", LANG_HUNGARIAN 
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Hungarian") 
3573    LNG(wxLANGUAGE_ICELANDIC
,                  "is_IS", LANG_ICELANDIC 
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Icelandic") 
3574    LNG(wxLANGUAGE_INDONESIAN
,                 "id_ID", LANG_INDONESIAN
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Indonesian") 
3575    LNG(wxLANGUAGE_INTERLINGUA
,                "ia"   , 0              , 0                                 , wxLayout_LeftToRight
, "Interlingua") 
3576    LNG(wxLANGUAGE_INTERLINGUE
,                "ie"   , 0              , 0                                 , wxLayout_LeftToRight
, "Interlingue") 
3577    LNG(wxLANGUAGE_INUKTITUT
,                  "iu"   , 0              , 0                                 , wxLayout_LeftToRight
, "Inuktitut") 
3578    LNG(wxLANGUAGE_INUPIAK
,                    "ik"   , 0              , 0                                 , wxLayout_LeftToRight
, "Inupiak") 
3579    LNG(wxLANGUAGE_IRISH
,                      "ga_IE", 0              , 0                                 , wxLayout_LeftToRight
, "Irish") 
3580    LNG(wxLANGUAGE_ITALIAN
,                    "it_IT", LANG_ITALIAN   
, SUBLANG_ITALIAN                   
, wxLayout_LeftToRight
, "Italian") 
3581    LNG(wxLANGUAGE_ITALIAN_SWISS
,              "it_CH", LANG_ITALIAN   
, SUBLANG_ITALIAN_SWISS             
, wxLayout_LeftToRight
, "Italian (Swiss)") 
3582    LNG(wxLANGUAGE_JAPANESE
,                   "ja_JP", LANG_JAPANESE  
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Japanese") 
3583    LNG(wxLANGUAGE_JAVANESE
,                   "jw"   , 0              , 0                                 , wxLayout_LeftToRight
, "Javanese") 
3584    LNG(wxLANGUAGE_KANNADA
,                    "kn"   , LANG_KANNADA   
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Kannada") 
3585    LNG(wxLANGUAGE_KASHMIRI
,                   "ks"   , LANG_KASHMIRI  
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Kashmiri") 
3586    LNG(wxLANGUAGE_KASHMIRI_INDIA
,             "ks_IN", LANG_KASHMIRI  
, SUBLANG_KASHMIRI_INDIA            
, wxLayout_LeftToRight
, "Kashmiri (India)") 
3587    LNG(wxLANGUAGE_KAZAKH
,                     "kk"   , LANG_KAZAK     
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Kazakh") 
3588    LNG(wxLANGUAGE_KERNEWEK
,                   "kw_GB", 0              , 0                                 , wxLayout_LeftToRight
, "Kernewek") 
3589    LNG(wxLANGUAGE_KINYARWANDA
,                "rw"   , 0              , 0                                 , wxLayout_LeftToRight
, "Kinyarwanda") 
3590    LNG(wxLANGUAGE_KIRGHIZ
,                    "ky"   , 0              , 0                                 , wxLayout_LeftToRight
, "Kirghiz") 
3591    LNG(wxLANGUAGE_KIRUNDI
,                    "rn"   , 0              , 0                                 , wxLayout_LeftToRight
, "Kirundi") 
3592    LNG(wxLANGUAGE_KONKANI
,                    ""     , LANG_KONKANI   
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Konkani") 
3593    LNG(wxLANGUAGE_KOREAN
,                     "ko_KR", LANG_KOREAN    
, SUBLANG_KOREAN                    
, wxLayout_LeftToRight
, "Korean") 
3594    LNG(wxLANGUAGE_KURDISH
,                    "ku"   , 0              , 0                                 , wxLayout_LeftToRight
, "Kurdish") 
3595    LNG(wxLANGUAGE_LAOTHIAN
,                   "lo"   , 0              , 0                                 , wxLayout_LeftToRight
, "Laothian") 
3596    LNG(wxLANGUAGE_LATIN
,                      "la"   , 0              , 0                                 , wxLayout_LeftToRight
, "Latin") 
3597    LNG(wxLANGUAGE_LATVIAN
,                    "lv_LV", LANG_LATVIAN   
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Latvian") 
3598    LNG(wxLANGUAGE_LINGALA
,                    "ln"   , 0              , 0                                 , wxLayout_LeftToRight
, "Lingala") 
3599    LNG(wxLANGUAGE_LITHUANIAN
,                 "lt_LT", LANG_LITHUANIAN
, SUBLANG_LITHUANIAN                
, wxLayout_LeftToRight
, "Lithuanian") 
3600    LNG(wxLANGUAGE_MACEDONIAN
,                 "mk_MK", LANG_MACEDONIAN
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Macedonian") 
3601    LNG(wxLANGUAGE_MALAGASY
,                   "mg"   , 0              , 0                                 , wxLayout_LeftToRight
, "Malagasy") 
3602    LNG(wxLANGUAGE_MALAY
,                      "ms_MY", LANG_MALAY     
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Malay") 
3603    LNG(wxLANGUAGE_MALAYALAM
,                  "ml"   , LANG_MALAYALAM 
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Malayalam") 
3604    LNG(wxLANGUAGE_MALAY_BRUNEI_DARUSSALAM
,    "ms_BN", LANG_MALAY     
, SUBLANG_MALAY_BRUNEI_DARUSSALAM   
, wxLayout_LeftToRight
, "Malay (Brunei Darussalam)") 
3605    LNG(wxLANGUAGE_MALAY_MALAYSIA
,             "ms_MY", LANG_MALAY     
, SUBLANG_MALAY_MALAYSIA            
, wxLayout_LeftToRight
, "Malay (Malaysia)") 
3606    LNG(wxLANGUAGE_MALTESE
,                    "mt_MT", 0              , 0                                 , wxLayout_LeftToRight
, "Maltese") 
3607    LNG(wxLANGUAGE_MANIPURI
,                   ""     , LANG_MANIPURI  
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Manipuri") 
3608    LNG(wxLANGUAGE_MAORI
,                      "mi"   , 0              , 0                                 , wxLayout_LeftToRight
, "Maori") 
3609    LNG(wxLANGUAGE_MARATHI
,                    "mr_IN", LANG_MARATHI   
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Marathi") 
3610    LNG(wxLANGUAGE_MOLDAVIAN
,                  "mo"   , 0              , 0                                 , wxLayout_LeftToRight
, "Moldavian") 
3611    LNG(wxLANGUAGE_MONGOLIAN
,                  "mn"   , 0              , 0                                 , wxLayout_LeftToRight
, "Mongolian") 
3612    LNG(wxLANGUAGE_NAURU
,                      "na"   , 0              , 0                                 , wxLayout_LeftToRight
, "Nauru") 
3613    LNG(wxLANGUAGE_NEPALI
,                     "ne"   , LANG_NEPALI    
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Nepali") 
3614    LNG(wxLANGUAGE_NEPALI_INDIA
,               "ne_IN", LANG_NEPALI    
, SUBLANG_NEPALI_INDIA              
, wxLayout_LeftToRight
, "Nepali (India)") 
3615    LNG(wxLANGUAGE_NORWEGIAN_BOKMAL
,           "nb_NO", LANG_NORWEGIAN 
, SUBLANG_NORWEGIAN_BOKMAL          
, wxLayout_LeftToRight
, "Norwegian (Bokmal)") 
3616    LNG(wxLANGUAGE_NORWEGIAN_NYNORSK
,          "nn_NO", LANG_NORWEGIAN 
, SUBLANG_NORWEGIAN_NYNORSK         
, wxLayout_LeftToRight
, "Norwegian (Nynorsk)") 
3617    LNG(wxLANGUAGE_OCCITAN
,                    "oc"   , 0              , 0                                 , wxLayout_LeftToRight
, "Occitan") 
3618    LNG(wxLANGUAGE_ORIYA
,                      "or"   , LANG_ORIYA     
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Oriya") 
3619    LNG(wxLANGUAGE_OROMO
,                      "om"   , 0              , 0                                 , wxLayout_LeftToRight
, "(Afan) Oromo") 
3620    LNG(wxLANGUAGE_PASHTO
,                     "ps"   , 0              , 0                                 , wxLayout_LeftToRight
, "Pashto, Pushto") 
3621    LNG(wxLANGUAGE_POLISH
,                     "pl_PL", LANG_POLISH    
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Polish") 
3622    LNG(wxLANGUAGE_PORTUGUESE
,                 "pt_PT", LANG_PORTUGUESE
, SUBLANG_PORTUGUESE                
, wxLayout_LeftToRight
, "Portuguese") 
3623    LNG(wxLANGUAGE_PORTUGUESE_BRAZILIAN
,       "pt_BR", LANG_PORTUGUESE
, SUBLANG_PORTUGUESE_BRAZILIAN      
, wxLayout_LeftToRight
, "Portuguese (Brazilian)") 
3624    LNG(wxLANGUAGE_PUNJABI
,                    "pa"   , LANG_PUNJABI   
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Punjabi") 
3625    LNG(wxLANGUAGE_QUECHUA
,                    "qu"   , 0              , 0                                 , wxLayout_LeftToRight
, "Quechua") 
3626    LNG(wxLANGUAGE_RHAETO_ROMANCE
,             "rm"   , 0              , 0                                 , wxLayout_LeftToRight
, "Rhaeto-Romance") 
3627    LNG(wxLANGUAGE_ROMANIAN
,                   "ro_RO", LANG_ROMANIAN  
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Romanian") 
3628    LNG(wxLANGUAGE_RUSSIAN
,                    "ru_RU", LANG_RUSSIAN   
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Russian") 
3629    LNG(wxLANGUAGE_RUSSIAN_UKRAINE
,            "ru_UA", 0              , 0                                 , wxLayout_LeftToRight
, "Russian (Ukraine)") 
3630    LNG(wxLANGUAGE_SAMOAN
,                     "sm"   , 0              , 0                                 , wxLayout_LeftToRight
, "Samoan") 
3631    LNG(wxLANGUAGE_SANGHO
,                     "sg"   , 0              , 0                                 , wxLayout_LeftToRight
, "Sangho") 
3632    LNG(wxLANGUAGE_SANSKRIT
,                   "sa"   , LANG_SANSKRIT  
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Sanskrit") 
3633    LNG(wxLANGUAGE_SCOTS_GAELIC
,               "gd"   , 0              , 0                                 , wxLayout_LeftToRight
, "Scots Gaelic") 
3634    LNG(wxLANGUAGE_SERBIAN_CYRILLIC
,           "sr_YU", LANG_SERBIAN   
, SUBLANG_SERBIAN_CYRILLIC          
, wxLayout_LeftToRight
, "Serbian (Cyrillic)") 
3635    LNG(wxLANGUAGE_SERBIAN_LATIN
,              "sr_YU", LANG_SERBIAN   
, SUBLANG_SERBIAN_LATIN             
, wxLayout_LeftToRight
, "Serbian (Latin)") 
3636    LNG(wxLANGUAGE_SERBO_CROATIAN
,             "sh"   , 0              , 0                                 , wxLayout_LeftToRight
, "Serbo-Croatian") 
3637    LNG(wxLANGUAGE_SESOTHO
,                    "st"   , 0              , 0                                 , wxLayout_LeftToRight
, "Sesotho") 
3638    LNG(wxLANGUAGE_SETSWANA
,                   "tn"   , 0              , 0                                 , wxLayout_LeftToRight
, "Setswana") 
3639    LNG(wxLANGUAGE_SHONA
,                      "sn"   , 0              , 0                                 , wxLayout_LeftToRight
, "Shona") 
3640    LNG(wxLANGUAGE_SINDHI
,                     "sd"   , LANG_SINDHI    
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Sindhi") 
3641    LNG(wxLANGUAGE_SINHALESE
,                  "si"   , 0              , 0                                 , wxLayout_LeftToRight
, "Sinhalese") 
3642    LNG(wxLANGUAGE_SISWATI
,                    "ss"   , 0              , 0                                 , wxLayout_LeftToRight
, "Siswati") 
3643    LNG(wxLANGUAGE_SLOVAK
,                     "sk_SK", LANG_SLOVAK    
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Slovak") 
3644    LNG(wxLANGUAGE_SLOVENIAN
,                  "sl_SI", LANG_SLOVENIAN 
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Slovenian") 
3645    LNG(wxLANGUAGE_SOMALI
,                     "so"   , 0              , 0                                 , wxLayout_LeftToRight
, "Somali") 
3646    LNG(wxLANGUAGE_SPANISH
,                    "es_ES", LANG_SPANISH   
, SUBLANG_SPANISH                   
, wxLayout_LeftToRight
, "Spanish") 
3647    LNG(wxLANGUAGE_SPANISH_ARGENTINA
,          "es_AR", LANG_SPANISH   
, SUBLANG_SPANISH_ARGENTINA         
, wxLayout_LeftToRight
, "Spanish (Argentina)") 
3648    LNG(wxLANGUAGE_SPANISH_BOLIVIA
,            "es_BO", LANG_SPANISH   
, SUBLANG_SPANISH_BOLIVIA           
, wxLayout_LeftToRight
, "Spanish (Bolivia)") 
3649    LNG(wxLANGUAGE_SPANISH_CHILE
,              "es_CL", LANG_SPANISH   
, SUBLANG_SPANISH_CHILE             
, wxLayout_LeftToRight
, "Spanish (Chile)") 
3650    LNG(wxLANGUAGE_SPANISH_COLOMBIA
,           "es_CO", LANG_SPANISH   
, SUBLANG_SPANISH_COLOMBIA          
, wxLayout_LeftToRight
, "Spanish (Colombia)") 
3651    LNG(wxLANGUAGE_SPANISH_COSTA_RICA
,         "es_CR", LANG_SPANISH   
, SUBLANG_SPANISH_COSTA_RICA        
, wxLayout_LeftToRight
, "Spanish (Costa Rica)") 
3652    LNG(wxLANGUAGE_SPANISH_DOMINICAN_REPUBLIC
, "es_DO", LANG_SPANISH   
, SUBLANG_SPANISH_DOMINICAN_REPUBLIC
, wxLayout_LeftToRight
, "Spanish (Dominican republic)") 
3653    LNG(wxLANGUAGE_SPANISH_ECUADOR
,            "es_EC", LANG_SPANISH   
, SUBLANG_SPANISH_ECUADOR           
, wxLayout_LeftToRight
, "Spanish (Ecuador)") 
3654    LNG(wxLANGUAGE_SPANISH_EL_SALVADOR
,        "es_SV", LANG_SPANISH   
, SUBLANG_SPANISH_EL_SALVADOR       
, wxLayout_LeftToRight
, "Spanish (El Salvador)") 
3655    LNG(wxLANGUAGE_SPANISH_GUATEMALA
,          "es_GT", LANG_SPANISH   
, SUBLANG_SPANISH_GUATEMALA         
, wxLayout_LeftToRight
, "Spanish (Guatemala)") 
3656    LNG(wxLANGUAGE_SPANISH_HONDURAS
,           "es_HN", LANG_SPANISH   
, SUBLANG_SPANISH_HONDURAS          
, wxLayout_LeftToRight
, "Spanish (Honduras)") 
3657    LNG(wxLANGUAGE_SPANISH_MEXICAN
,            "es_MX", LANG_SPANISH   
, SUBLANG_SPANISH_MEXICAN           
, wxLayout_LeftToRight
, "Spanish (Mexican)") 
3658    LNG(wxLANGUAGE_SPANISH_MODERN
,             "es_ES", LANG_SPANISH   
, SUBLANG_SPANISH_MODERN            
, wxLayout_LeftToRight
, "Spanish (Modern)") 
3659    LNG(wxLANGUAGE_SPANISH_NICARAGUA
,          "es_NI", LANG_SPANISH   
, SUBLANG_SPANISH_NICARAGUA         
, wxLayout_LeftToRight
, "Spanish (Nicaragua)") 
3660    LNG(wxLANGUAGE_SPANISH_PANAMA
,             "es_PA", LANG_SPANISH   
, SUBLANG_SPANISH_PANAMA            
, wxLayout_LeftToRight
, "Spanish (Panama)") 
3661    LNG(wxLANGUAGE_SPANISH_PARAGUAY
,           "es_PY", LANG_SPANISH   
, SUBLANG_SPANISH_PARAGUAY          
, wxLayout_LeftToRight
, "Spanish (Paraguay)") 
3662    LNG(wxLANGUAGE_SPANISH_PERU
,               "es_PE", LANG_SPANISH   
, SUBLANG_SPANISH_PERU              
, wxLayout_LeftToRight
, "Spanish (Peru)") 
3663    LNG(wxLANGUAGE_SPANISH_PUERTO_RICO
,        "es_PR", LANG_SPANISH   
, SUBLANG_SPANISH_PUERTO_RICO       
, wxLayout_LeftToRight
, "Spanish (Puerto Rico)") 
3664    LNG(wxLANGUAGE_SPANISH_URUGUAY
,            "es_UY", LANG_SPANISH   
, SUBLANG_SPANISH_URUGUAY           
, wxLayout_LeftToRight
, "Spanish (Uruguay)") 
3665    LNG(wxLANGUAGE_SPANISH_US
,                 "es_US", 0              , 0                                 , wxLayout_LeftToRight
, "Spanish (U.S.)") 
3666    LNG(wxLANGUAGE_SPANISH_VENEZUELA
,          "es_VE", LANG_SPANISH   
, SUBLANG_SPANISH_VENEZUELA         
, wxLayout_LeftToRight
, "Spanish (Venezuela)") 
3667    LNG(wxLANGUAGE_SUNDANESE
,                  "su"   , 0              , 0                                 , wxLayout_LeftToRight
, "Sundanese") 
3668    LNG(wxLANGUAGE_SWAHILI
,                    "sw_KE", LANG_SWAHILI   
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Swahili") 
3669    LNG(wxLANGUAGE_SWEDISH
,                    "sv_SE", LANG_SWEDISH   
, SUBLANG_SWEDISH                   
, wxLayout_LeftToRight
, "Swedish") 
3670    LNG(wxLANGUAGE_SWEDISH_FINLAND
,            "sv_FI", LANG_SWEDISH   
, SUBLANG_SWEDISH_FINLAND           
, wxLayout_LeftToRight
, "Swedish (Finland)") 
3671    LNG(wxLANGUAGE_TAGALOG
,                    "tl_PH", 0              , 0                                 , wxLayout_LeftToRight
, "Tagalog") 
3672    LNG(wxLANGUAGE_TAJIK
,                      "tg"   , 0              , 0                                 , wxLayout_LeftToRight
, "Tajik") 
3673    LNG(wxLANGUAGE_TAMIL
,                      "ta"   , LANG_TAMIL     
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Tamil") 
3674    LNG(wxLANGUAGE_TATAR
,                      "tt"   , LANG_TATAR     
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Tatar") 
3675    LNG(wxLANGUAGE_TELUGU
,                     "te"   , LANG_TELUGU    
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Telugu") 
3676    LNG(wxLANGUAGE_THAI
,                       "th_TH", LANG_THAI      
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Thai") 
3677    LNG(wxLANGUAGE_TIBETAN
,                    "bo"   , 0              , 0                                 , wxLayout_LeftToRight
, "Tibetan") 
3678    LNG(wxLANGUAGE_TIGRINYA
,                   "ti"   , 0              , 0                                 , wxLayout_LeftToRight
, "Tigrinya") 
3679    LNG(wxLANGUAGE_TONGA
,                      "to"   , 0              , 0                                 , wxLayout_LeftToRight
, "Tonga") 
3680    LNG(wxLANGUAGE_TSONGA
,                     "ts"   , 0              , 0                                 , wxLayout_LeftToRight
, "Tsonga") 
3681    LNG(wxLANGUAGE_TURKISH
,                    "tr_TR", LANG_TURKISH   
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Turkish") 
3682    LNG(wxLANGUAGE_TURKMEN
,                    "tk"   , 0              , 0                                 , wxLayout_LeftToRight
, "Turkmen") 
3683    LNG(wxLANGUAGE_TWI
,                        "tw"   , 0              , 0                                 , wxLayout_LeftToRight
, "Twi") 
3684    LNG(wxLANGUAGE_UIGHUR
,                     "ug"   , 0              , 0                                 , wxLayout_LeftToRight
, "Uighur") 
3685    LNG(wxLANGUAGE_UKRAINIAN
,                  "uk_UA", LANG_UKRAINIAN 
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Ukrainian") 
3686    LNG(wxLANGUAGE_URDU
,                       "ur"   , LANG_URDU      
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Urdu") 
3687    LNG(wxLANGUAGE_URDU_INDIA
,                 "ur_IN", LANG_URDU      
, SUBLANG_URDU_INDIA                
, wxLayout_LeftToRight
, "Urdu (India)") 
3688    LNG(wxLANGUAGE_URDU_PAKISTAN
,              "ur_PK", LANG_URDU      
, SUBLANG_URDU_PAKISTAN             
, wxLayout_LeftToRight
, "Urdu (Pakistan)") 
3689    LNG(wxLANGUAGE_UZBEK
,                      "uz"   , LANG_UZBEK     
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Uzbek") 
3690    LNG(wxLANGUAGE_UZBEK_CYRILLIC
,             "uz"   , LANG_UZBEK     
, SUBLANG_UZBEK_CYRILLIC            
, wxLayout_LeftToRight
, "Uzbek (Cyrillic)") 
3691    LNG(wxLANGUAGE_UZBEK_LATIN
,                "uz"   , LANG_UZBEK     
, SUBLANG_UZBEK_LATIN               
, wxLayout_LeftToRight
, "Uzbek (Latin)") 
3692    LNG(wxLANGUAGE_VIETNAMESE
,                 "vi_VN", LANG_VIETNAMESE
, SUBLANG_DEFAULT                   
, wxLayout_LeftToRight
, "Vietnamese") 
3693    LNG(wxLANGUAGE_VOLAPUK
,                    "vo"   , 0              , 0                                 , wxLayout_LeftToRight
, "Volapuk") 
3694    LNG(wxLANGUAGE_WELSH
,                      "cy"   , 0              , 0                                 , wxLayout_LeftToRight
, "Welsh") 
3695    LNG(wxLANGUAGE_WOLOF
,                      "wo"   , 0              , 0                                 , wxLayout_LeftToRight
, "Wolof") 
3696    LNG(wxLANGUAGE_XHOSA
,                      "xh"   , 0              , 0                                 , wxLayout_LeftToRight
, "Xhosa") 
3697    LNG(wxLANGUAGE_YIDDISH
,                    "yi"   , 0              , 0                                 , wxLayout_LeftToRight
, "Yiddish") 
3698    LNG(wxLANGUAGE_YORUBA
,                     "yo"   , 0              , 0                                 , wxLayout_LeftToRight
, "Yoruba") 
3699    LNG(wxLANGUAGE_ZHUANG
,                     "za"   , 0              , 0                                 , wxLayout_LeftToRight
, "Zhuang") 
3700    LNG(wxLANGUAGE_ZULU
,                       "zu"   , 0              , 0                                 , wxLayout_LeftToRight
, "Zulu") 
3704 // --- --- --- generated code ends here --- --- --- 
3706 #endif // wxUSE_INTL