]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/intl.cpp
made the #error message less self-contradictory
[wxWidgets.git] / src / common / intl.cpp
index e8b3ea68180d183ca25c174f3defe85c8ad22e03..92185e3f22b979524be07d631e1819cae854df7c 100644 (file)
@@ -147,7 +147,7 @@ static inline wxString ExtractNotLang(const wxString& langFull)
 // This is a "low-level" class and is used only by wxMsgCatalog
 // ----------------------------------------------------------------------------
 
-WX_DECLARE_STRING_HASH_MAP(wxString, wxMessagesHash)
+WX_DECLARE_EXPORTED_STRING_HASH_MAP(wxString, wxMessagesHash);
 
 class wxMsgCatalogFile
 {
@@ -194,7 +194,7 @@ private:
 
     const char *StringAtOfs(wxMsgTableEntry *pTable, size_t32 index) const
       { return (const char *)(m_pData + Swap(pTable[index].ofsString)); }
-      
+
     wxString GetCharset() const;
 
     // utility functions
@@ -202,6 +202,8 @@ private:
     inline size_t32 Swap(size_t32 ui) const;
 
     bool          m_bSwapped;   // wrong endianness?
+
+    DECLARE_NO_COPY_CLASS(wxMsgCatalogFile)
 };
 
 
@@ -300,6 +302,15 @@ static wxString GetFullSearchPath(const wxChar *lang)
     if ( pszLcPath != NULL )
         searchPath << GetAllMsgCatalogSubdirs(pszLcPath, lang);
 
+#ifdef __UNIX__
+    // add some standard ones and the one in the tree where wxWin was installed:
+    searchPath
+        << GetAllMsgCatalogSubdirs(wxString(wxGetInstallPrefix()) + wxT("/share/locale"), lang)
+        << GetAllMsgCatalogSubdirs(wxT("/usr/share/locale"), lang)
+        << GetAllMsgCatalogSubdirs(wxT("/usr/lib/locale"), lang)
+        << GetAllMsgCatalogSubdirs(wxT("/usr/local/share/locale"), lang);
+#endif // __UNIX__
+
     // then take the current directory
     // FIXME it should be the directory of the executable
 #ifdef __WXMAC__
@@ -307,15 +318,11 @@ static wxString GetFullSearchPath(const wxChar *lang)
     wxGetWorkingDirectory( cwd , sizeof( cwd ) ) ;
     searchPath << GetAllMsgCatalogSubdirs(cwd, lang);
     // generic search paths could be somewhere in the system folder preferences
-#else
+#else // !Mac
     searchPath << GetAllMsgCatalogSubdirs(wxT("."), lang);
 
-    // and finally add some standard ones
-    searchPath
-        << GetAllMsgCatalogSubdirs(wxT("/usr/share/locale"), lang)
-        << GetAllMsgCatalogSubdirs(wxT("/usr/lib/locale"), lang)
-        << GetAllMsgCatalogSubdirs(wxT("/usr/local/share/locale"), lang);
-#endif
+#endif // platform
+
     return searchPath;
 }
 
@@ -430,7 +437,7 @@ void wxMsgCatalogFile::FillHash(wxMessagesHash& hash, bool convertEncoding) cons
         hash[key] = wxString(StringAtOfs(m_pTransTable, i), inputConv);
     #else
         if ( convertEncoding )
-            hash[key] = 
+            hash[key] =
                 wxString(inputConv.cMB2WC(StringAtOfs(m_pTransTable, i)),
                          wxConvLocal);
         else
@@ -444,7 +451,7 @@ void wxMsgCatalogFile::FillHash(wxMessagesHash& hash, bool convertEncoding) cons
     if ( convertEncoding )
     {
         wxFontEncoding targetEnc = wxFONTENCODING_SYSTEM;
-        wxFontEncoding enc = wxTheFontMapper->CharsetToEncoding(charset, FALSE);
+        wxFontEncoding enc = wxFontMapper::Get()->CharsetToEncoding(charset, FALSE);
         if ( enc == wxFONTENCODING_SYSTEM )
         {
             convertEncoding = FALSE; // unknown encoding
@@ -457,7 +464,7 @@ void wxMsgCatalogFile::FillHash(wxMessagesHash& hash, bool convertEncoding) cons
                 wxFontEncodingArray a = wxEncodingConverter::GetPlatformEquivalents(enc);
                 if (a[0] == enc)
                     // no conversion needed, locale uses native encoding
-                    convertEncoding = FALSE; 
+                    convertEncoding = FALSE;
                 if (a.GetCount() == 0)
                     // we don't know common equiv. under this platform
                     convertEncoding = FALSE;
@@ -473,7 +480,7 @@ void wxMsgCatalogFile::FillHash(wxMessagesHash& hash, bool convertEncoding) cons
             for (size_t i = 0; i < m_numStrings; i++)
             {
                 wxString key(StringAtOfs(m_pOrigTable, i));
-                hash[key] = 
+                hash[key] =
                     converter.Convert(wxString(StringAtOfs(m_pTransTable, i)));
             }
         }
@@ -495,31 +502,31 @@ wxString wxMsgCatalogFile::GetCharset() const
 {
     // first, find encoding header:
     const char *hdr = StringAtOfs(m_pOrigTable, 0);
-    if ( hdr == NULL || hdr[0] != 0 ) 
+    if ( hdr == NULL || hdr[0] != 0 )
     {
         // not supported by this catalog, does not have correct header
         return wxEmptyString;
     }
 
-    wxString header(StringAtOfs(m_pTransTable, 0));
+    wxString header = wxString::FromAscii( StringAtOfs(m_pTransTable, 0));
     wxString charset;
     int pos = header.Find(wxT("Content-Type: text/plain; charset="));
     if ( pos == wxNOT_FOUND )
     {
         // incorrectly filled Content-Type header
-        return wxEmptyString; 
+        return wxEmptyString;
     }
 
     size_t n = pos + 34; /*strlen("Content-Type: text/plain; charset=")*/
     while ( header[n] != wxT('\n') )
         charset << header[n++];
-    
+
     if ( charset == wxT("CHARSET") )
     {
         // "CHARSET" is not valid charset, but lazy translator
         return wxEmptyString;
     }
-        
+
     return charset;
 }
 
@@ -527,13 +534,13 @@ wxString wxMsgCatalogFile::GetCharset() const
 // wxMsgCatalog class
 // ----------------------------------------------------------------------------
 
-bool wxMsgCatalog::Load(const wxChar *szDirPrefix, const wxChar *szName, 
+bool wxMsgCatalog::Load(const wxChar *szDirPrefix, const wxChar *szName,
                         bool bConvertEncoding)
 {
     wxMsgCatalogFile file;
-    
+
     m_name = szName;
-    
+
     if ( file.Load(szDirPrefix, szName) )
     {
         file.FillHash(m_messages, bConvertEncoding);
@@ -636,11 +643,7 @@ bool wxLocale::Init(const wxChar *szName,
 
 bool wxLocale::Init(int language, int flags)
 {
-    wxLanguageInfo *info = NULL;
     int lang = language;
-
-    CreateLanguagesDB();
-
     if (lang == wxLANGUAGE_DEFAULT)
     {
         // auto detect the language
@@ -653,17 +656,7 @@ bool wxLocale::Init(int language, int flags)
        return FALSE;
     }
 
-    if (lang != wxLANGUAGE_DEFAULT)
-    {
-        for (size_t i = 0; i < ms_languagesDB->GetCount(); i++)
-        {
-            if (ms_languagesDB->Item(i).Language == lang)
-            {
-                info = &ms_languagesDB->Item(i);
-                break;
-            }
-        }
-    }
+    const wxLanguageInfo *info = GetLanguageInfo(lang);
 
     // Unknown language:
     if (info == NULL)
@@ -675,57 +668,63 @@ bool wxLocale::Init(int language, int flags)
     wxString name = info->Description;
     wxString canonical = info->CanonicalName;
     wxString locale;
-    const wxChar *retloc;
 
     // Set the locale:
-#ifdef __UNIX__
+#if defined(__UNIX__) && !defined(__WXMAC__)
     if (language == wxLANGUAGE_DEFAULT)
         locale = wxEmptyString;
     else
         locale = info->CanonicalName;
 
-    retloc = wxSetlocale(LC_ALL, locale);
+    wxMB2WXbuf retloc = wxSetlocale(LC_ALL, locale);
 
-    if (retloc == NULL)
+    if ( !retloc )
     {
         // Some C libraries don't like xx_YY form and require xx only
         retloc = wxSetlocale(LC_ALL, locale.Mid(0,2));
     }
-    if (retloc == NULL)
+    if ( !retloc )
     {
         // Some C libraries (namely glibc) still use old ISO 639,
         // so will translate the abbrev for them
         wxString mid = locale.Mid(0,2);
-        if (mid == wxT("he")) locale = wxT("iw") + locale.Mid(3);
-        else if (mid == wxT("id")) locale = wxT("in") + locale.Mid(3);
-        else if (mid == wxT("yi")) locale = wxT("ji") + locale.Mid(3);
+        if (mid == wxT("he"))
+            locale = wxT("iw") + locale.Mid(3);
+        else if (mid == wxT("id"))
+            locale = wxT("in") + locale.Mid(3);
+        else if (mid == wxT("yi"))
+            locale = wxT("ji") + locale.Mid(3);
+
         retloc = wxSetlocale(LC_ALL, locale);
     }
-    if (retloc == NULL)
+    if ( !retloc )
     {
         // (This time, we changed locale in previous if-branch, so try again.)
         // Some C libraries don't like xx_YY form and require xx only
         retloc = wxSetlocale(LC_ALL, locale.Mid(0,2));
     }
-    if (retloc == NULL)
+    if ( !retloc )
     {
         wxLogError(wxT("Cannot set locale to '%s'."), locale.c_str());
         return FALSE;
     }
 #elif defined(__WIN32__)
+    wxMB2WXbuf retloc = wxT("C");
     if (language != wxLANGUAGE_DEFAULT)
     {
         if (info->WinLang == 0)
         {
             wxLogWarning(wxT("Locale '%s' not supported by OS."), name.c_str());
-            retloc = wxT("C");
+            // retloc already set to "C"
         }
         else
         {
             wxUint32 lcid = MAKELCID(MAKELANGID(info->WinLang, info->WinSublang),
                                      SORT_DEFAULT);
             if (SetThreadLocale(lcid))
+            {
                 retloc = wxSetlocale(LC_ALL, wxEmptyString);
+            }
             else
             {
                 // Windows9X doesn't support SetThreadLocale, so we must
@@ -747,25 +746,29 @@ bool wxLocale::Init(int language, int flags)
                     return FALSE;
                 }
                 else
+                {
                     retloc = wxSetlocale(LC_ALL, locale);
+                }
             }
         }
     }
     else
+    {
         retloc = wxSetlocale(LC_ALL, wxEmptyString);
+    }
 
-    if (retloc == NULL)
+    if ( !retloc )
     {
         wxLogError(wxT("Cannot set locale to language %s."), name.c_str());
         return FALSE;
     }
-#elif defined(__WXMAC__)
-    retloc = wxSetlocale(LC_ALL , wxEmptyString);
+#elif defined(__WXMAC__) || defined(__WXPM__)
+    wxMB2WXbuf retloc = wxSetlocale(LC_ALL , wxEmptyString);
 #else
     return FALSE;
 #endif
 
-    return Init(name, canonical, wxString(retloc),
+    return Init(name, canonical, retloc,
                 (flags & wxLOCALE_LOAD_DEFAULT) != 0,
                 (flags & wxLOCALE_CONV_ENCODING) != 0);
 }
@@ -789,7 +792,7 @@ void wxLocale::AddCatalogLookupPathPrefix(const wxString& prefix)
     size_t i = 0,
            count = ms_languagesDB->GetCount();
 
-#if defined(__UNIX__)
+#if defined(__UNIX__) && !defined(__WXMAC__)
     // first get the string identifying the language from the environment
     wxString langFull;
     if (!wxGetEnv(wxT("LC_ALL"), &langFull) &&
@@ -912,7 +915,7 @@ void wxLocale::AddCatalogLookupPathPrefix(const wxString& prefix)
         }
     }
 #elif defined(__WXMAC__)
-    char* lc = NULL ;
+    const char* lc = NULL ;
     long lang = GetScriptVariable( smSystemScript, smScriptLang) ;
     switch( GetScriptManagerVariable( smRegionCode ) ) {
       case verUS :
@@ -1196,7 +1199,7 @@ void wxLocale::AddCatalogLookupPathPrefix(const wxString& prefix)
           break;
       }
   }
-    
+
 #elif defined(__WIN32__)
     LCID lcid = GetUserDefaultLCID();
     if ( lcid != 0 )
@@ -1253,20 +1256,25 @@ wxString wxLocale::GetSystemEncodingName()
     char *alang = nl_langinfo(CODESET);
     setlocale(LC_CTYPE, oldLocale);
     free(oldLocale);
-    if (alang)
+
+    if ( alang )
     {
-#ifdef __SOLARIS__
+        // 7 bit ASCII encoding has several alternative names which we should
+        // recognize to avoid warnings about unrecognized encoding on each
+        // program startup
+
         // nl_langinfo() under Solaris returns 646 by default which stands for
-        // ISO-646, i.e. 7 bit ASCII and we should recognize it to avoid
-        // warnings about unrecognized encoding on each program startup
-        if ( strcmp(alang, "646") == 0 )
+        // ISO-646, i.e. 7 bit ASCII
+        //
+        // and recent glibc call it ANSI_X3.4-1968...
+        if ( strcmp(alang, "646") == 0 ||
+               strcmp(alang, "ANSI_X3.4-1968") == 0 )
         {
             encname = _T("US-ASCII");
         }
         else
-#endif // __SOLARIS__
         {
-            encname = wxConvLibc.cMB2WX(alang);
+            encname = wxString::FromAscii( alang );
         }
     }
     else
@@ -1275,24 +1283,24 @@ wxString wxLocale::GetSystemEncodingName()
         // if we can't get at the character set directly, try to see if it's in
         // the environment variables (in most cases this won't work, but I was
         // out of ideas)
-        wxChar *lang = wxGetenv(wxT("LC_ALL"));
-        wxChar *dot = lang ? wxStrchr(lang, wxT('.')) : (wxChar *)NULL;
+        char *lang = getenv( "LC_ALL");
+        char *dot = lang ? strchr(lang, '.') : (char *)NULL;
         if (!dot)
         {
-            lang = wxGetenv(wxT("LC_CTYPE"));
+            lang = getenv( "LC_CTYPE" );
             if ( lang )
-                dot = wxStrchr(lang, wxT('.'));
+                dot = strchr(lang, '.' );
         }
         if (!dot)
         {
-            lang = wxGetenv(wxT("LANG"));
+            lang = getenv( "LANG");
             if ( lang )
-                dot = wxStrchr(lang, wxT('.'));
+                dot = strchr(lang, '.');
         }
 
         if ( dot )
         {
-            encname = dot+1;
+            encname = wxString::FromAscii( dot+1 );
         }
     }
 #endif // Win32/Unix
@@ -1335,9 +1343,20 @@ wxFontEncoding wxLocale::GetSystemEncoding()
     wxString encname = GetSystemEncodingName();
     if ( !encname.empty() )
     {
-        wxFontEncoding enc = wxTheFontMapper->
+        wxFontEncoding enc = wxFontMapper::Get()->
             CharsetToEncoding(encname, FALSE /* not interactive */);
 
+        // on some modern Linux systems (RedHat 8) the default system locale
+        // is UTF8 -- but it isn't supported by wxGTK in ANSI build at all so
+        // don't even try to use it in this case
+#if !wxUSE_UNICODE
+        if ( enc == wxFONTENCODING_UTF8 )
+        {
+            // the most similar supported encoding...
+            enc = wxFONTENCODING_ISO8859_1;
+        }
+#endif // !wxUSE_UNICODE
+
         // this should probably be considered as a bug in CharsetToEncoding():
         // it shouldn't return wxFONTENCODING_DEFAULT at all - but it does it
         // for US-ASCII charset
@@ -1355,12 +1374,30 @@ wxFontEncoding wxLocale::GetSystemEncoding()
     return wxFONTENCODING_SYSTEM;
 }
 
-/*static*/ void wxLocale::AddLanguage(const wxLanguageInfo& info)
+/* static */
+void wxLocale::AddLanguage(const wxLanguageInfo& info)
 {
     CreateLanguagesDB();
     ms_languagesDB->Add(info);
 }
 
+/* static */
+const wxLanguageInfo *wxLocale::GetLanguageInfo(int lang)
+{
+    CreateLanguagesDB();
+
+    size_t count = ms_languagesDB->GetCount();
+    for ( size_t i = 0; i < count; i++ )
+    {
+        if ( ms_languagesDB->Item(i).Language == lang )
+        {
+            return &ms_languagesDB->Item(i);
+        }
+    }
+
+    return NULL;
+}
+
 wxString wxLocale::GetSysName() const
 {
     return wxSetlocale(LC_ALL, NULL);
@@ -1392,7 +1429,7 @@ const wxChar *wxLocale::GetString(const wxChar *szOrigString,
     const wxChar *pszTrans = NULL;
     wxMsgCatalog *pMsgCat;
 
-    if ( szDomain != NULL ) 
+    if ( szDomain != NULL )
     {
         pMsgCat = FindCatalog(szDomain);
 
@@ -1400,10 +1437,10 @@ const wxChar *wxLocale::GetString(const wxChar *szOrigString,
         if ( pMsgCat != NULL )
             pszTrans = pMsgCat->GetString(szOrigString);
     }
-    else 
+    else
     {
         // search in all domains
-        for ( pMsgCat = m_pMsgCat; pMsgCat != NULL; pMsgCat = pMsgCat->m_pNext ) 
+        for ( pMsgCat = m_pMsgCat; pMsgCat != NULL; pMsgCat = pMsgCat->m_pNext )
         {
             pszTrans = pMsgCat->GetString(szOrigString);
             if ( pszTrans != NULL )   // take the first found
@@ -1411,21 +1448,23 @@ const wxChar *wxLocale::GetString(const wxChar *szOrigString,
         }
     }
 
-    if ( pszTrans == NULL ) 
+    if ( pszTrans == NULL )
     {
 #ifdef __WXDEBUG__
-        if ( !NoTransErr::Suppress() ) 
+        if ( !NoTransErr::Suppress() )
         {
             NoTransErr noTransErr;
 
             if ( szDomain != NULL )
             {
-                wxLogDebug(_T("string '%s' not found in domain '%s' for locale '%s'."),
-                             szOrigString, szDomain, m_strLocale.c_str());
+                wxLogTrace(_T("i18n"),
+                           _T("string '%s' not found in domain '%s' for locale '%s'."),
+                           szOrigString, szDomain, m_strLocale.c_str());
             }
             else
             {
-                wxLogDebug(_T("string '%s' not found in locale '%s'."),
+                wxLogTrace(_T("i18n"),
+                           _T("string '%s' not found in locale '%s'."),
                            szOrigString, m_strLocale.c_str());
             }
         }
@@ -1442,7 +1481,7 @@ wxMsgCatalog *wxLocale::FindCatalog(const wxChar *szDomain) const
 {
     // linear search in the linked list
     wxMsgCatalog *pMsgCat;
-    for ( pMsgCat = m_pMsgCat; pMsgCat != NULL; pMsgCat = pMsgCat->m_pNext ) 
+    for ( pMsgCat = m_pMsgCat; pMsgCat != NULL; pMsgCat = pMsgCat->m_pNext )
     {
         if ( wxStricmp(pMsgCat->GetName(), szDomain) == 0 )
           return pMsgCat;
@@ -2079,7 +2118,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxLocaleModule, wxModule)
 #define LNG(wxlang, canonical, winlang, winsublang, desc) \
     info.Language = wxlang;                               \
     info.CanonicalName = wxT(canonical);                  \
-    info.Description = desc;                              \
+    info.Description = wxT(desc);                         \
     SETWINLANG(info, winlang, winsublang)                 \
     AddLanguage(info);
 
@@ -2088,7 +2127,7 @@ void wxLocale::InitLanguagesDB()
    wxLanguageInfo info;
    wxStringTokenizer tkn;
 
-      LNG(wxLANGUAGE_ABKHAZIAN,                  "ab"   , 0              , 0                                 , "Abkhazian")
+   LNG(wxLANGUAGE_ABKHAZIAN,                  "ab"   , 0              , 0                                 , "Abkhazian")
    LNG(wxLANGUAGE_AFAR,                       "aa"   , 0              , 0                                 , "Afar")
    LNG(wxLANGUAGE_AFRIKAANS,                  "af_ZA", LANG_AFRIKAANS , SUBLANG_DEFAULT                   , "Afrikaans")
    LNG(wxLANGUAGE_ALBANIAN,                   "sq_AL", LANG_ALBANIAN  , SUBLANG_DEFAULT                   , "Albanian")
@@ -2135,7 +2174,7 @@ void wxLocale::InitLanguagesDB()
    LNG(wxLANGUAGE_CHINESE_HONGKONG,           "zh_HK", LANG_CHINESE   , SUBLANG_CHINESE_HONGKONG          , "Chinese (Hongkong)")
    LNG(wxLANGUAGE_CHINESE_MACAU,              "zh_MO", LANG_CHINESE   , SUBLANG_CHINESE_MACAU             , "Chinese (Macau)")
    LNG(wxLANGUAGE_CHINESE_SINGAPORE,          "zh_SG", LANG_CHINESE   , SUBLANG_CHINESE_SINGAPORE         , "Chinese (Singapore)")
-   LNG(wxLANGUAGE_CHINESE_TAIWAN,             "zh_TW", 0              , 0                                 , "Chinese (Taiwan)")
+   LNG(wxLANGUAGE_CHINESE_TAIWAN,             "zh_TW", LANG_CHINESE   , SUBLANG_CHINESE_TRADITIONAL       , "Chinese (Taiwan)")
    LNG(wxLANGUAGE_CORSICAN,                   "co"   , 0              , 0                                 , "Corsican")
    LNG(wxLANGUAGE_CROATIAN,                   "hr_HR", LANG_CROATIAN  , SUBLANG_DEFAULT                   , "Croatian")
    LNG(wxLANGUAGE_CZECH,                      "cs_CZ", LANG_CZECH     , SUBLANG_DEFAULT                   , "Czech")
@@ -2316,7 +2355,7 @@ void wxLocale::InitLanguagesDB()
    LNG(wxLANGUAGE_YORUBA,                     "yo"   , 0              , 0                                 , "Yoruba")
    LNG(wxLANGUAGE_ZHUANG,                     "za"   , 0              , 0                                 , "Zhuang")
    LNG(wxLANGUAGE_ZULU,                       "zu"   , 0              , 0                                 , "Zulu")
-   
+
 };
 #undef LNG