]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/intl.cpp
added vendor display name (for consistency with app display name &c) (patch 1831303)
[wxWidgets.git] / src / common / intl.cpp
index db82ff55a3b3b31cd02a9de2bd6a3ea6726e6ce8..24ef9a4a1b6d45bf79998e317e9f5dcab109bdfe 100644 (file)
 // headers
 // ----------------------------------------------------------------------------
 
-#ifdef __EMX__
-// The following define is needed by Innotek's libc to
-// make the definition of struct localeconv available.
-#define __INTERNAL_DEFS
-#endif
-
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
     #pragma hdrstop
 #endif
 
+#ifdef __EMX__
+// The following define is needed by Innotek's libc to
+// make the definition of struct localeconv available.
+#define __INTERNAL_DEFS
+#endif
+
 #if wxUSE_INTL
 
 #ifndef WX_PRECOMP
 #include "wx/apptrait.h"
 #include "wx/stdpaths.h"
 #include "wx/hashset.h"
+#include "wx/filesys.h"
 
 #if defined(__WXMAC__)
-    #include  "wx/mac/private.h"  // includes mac headers
+    #include "wx/mac/private.h"  // includes mac headers
 #endif
 
 // ----------------------------------------------------------------------------
@@ -907,11 +908,8 @@ private:
                 ofsHashTable;   //        +18:  offset of hash table start
     };
 
-    // all data is stored here, NULL if no data loaded
-    size_t8 *m_pData;
-
-    // amount of memory pointed to by m_pData.
-    size_t32 m_nSize;
+    // all data is stored here
+    wxMemoryBuffer m_data;
 
     // data description
     size_t32          m_numStrings;   // number of strings in this domain
@@ -929,18 +927,25 @@ private:
                             : ui;
     }
 
+    // just return the pointer to the start of the data as "char *" to
+    // facilitate doing pointer arithmetic with it
+    char *StringData() const
+    {
+        return wx_static_cast(char *, m_data.GetData());
+    }
+
     const char *StringAtOfs(wxMsgTableEntry *pTable, size_t32 n) const
     {
         const wxMsgTableEntry * const ent = pTable + n;
 
         // this check could fail for a corrupt message catalog
         size_t32 ofsString = Swap(ent->ofsString);
-        if ( ofsString + Swap(ent->nLen) > m_nSize)
+        if ( ofsString + Swap(ent->nLen) > m_data.GetDataLen())
         {
             return NULL;
         }
 
-        return (const char *)(m_pData + ofsString);
+        return StringData() + ofsString;
     }
 
     bool m_bSwapped;   // wrong endianness?
@@ -1003,13 +1008,10 @@ static wxArrayString gs_searchPrefixes;
 
 wxMsgCatalogFile::wxMsgCatalogFile()
 {
-    m_pData = NULL;
-    m_nSize = 0;
 }
 
 wxMsgCatalogFile::~wxMsgCatalogFile()
 {
-    delete [] m_pData;
 }
 
 // return the directories to search for message catalogs under the given
@@ -1017,21 +1019,25 @@ wxMsgCatalogFile::~wxMsgCatalogFile()
 static
 wxString GetMsgCatalogSubdirs(const wxString& prefix, const wxString& lang)
 {
-    wxString searchPath;
-    searchPath << prefix << wxFILE_SEP_PATH << lang;
-
-    // Under Unix, the message catalogs are supposed to go into LC_MESSAGES
-    // subdirectory so look there too. Note that we do it on all platforms
-    // and not just Unix, because it doesn't cost much to look into one more
-    // directory and doing it this way has two important benefits:
+    // Search first in Unix-standard prefix/lang/LC_MESSAGES, then in
+    // prefix/lang and finally in just prefix.
+    //
+    // Note that we use LC_MESSAGES on all platforms and not just Unix, because
+    // it doesn't cost much to look into one more directory and doing it this
+    // way has two important benefits:
     // a) we don't break compatibility with wx-2.6 and older by stopping to
     //    look in a directory where the catalogs used to be and thus silently
     //    breaking apps after they are recompiled against the latest wx
     // b) it makes it possible to package app's support files in the same
     //    way on all target platforms
-    const wxString searchPathOrig(searchPath);
-    searchPath << wxFILE_SEP_PATH << wxT("LC_MESSAGES")
-               << wxPATH_SEP << searchPathOrig;
+    wxString pathPrefix;
+    pathPrefix << prefix << wxFILE_SEP_PATH << lang;
+
+    wxString searchPath;
+    searchPath.reserve(4*pathPrefix.length());
+    searchPath << pathPrefix << wxFILE_SEP_PATH << "LC_MESSAGES" << wxPATH_SEP
+               << prefix << wxFILE_SEP_PATH << wxPATH_SEP
+               << pathPrefix;
 
     return searchPath;
 }
@@ -1141,17 +1147,40 @@ bool wxMsgCatalogFile::Load(const wxString& szDirPrefix, const wxString& szName,
 
   wxFileName fn(szName);
   fn.SetExt(_T("mo"));
+
   wxString strFullName;
-  if ( !wxFindFileInPath(&strFullName, searchPath, fn.GetFullPath()) ) {
+#if wxUSE_FILESYSTEM
+  wxFileSystem fileSys;
+  if ( !fileSys.FindFileInPath(&strFullName, searchPath, fn.GetFullPath()) )
+#else // !wxUSE_FILESYSTEM
+  if ( !wxFindFileInPath(&strFullName, searchPath, fn.GetFullPath()) )
+#endif // wxUSE_FILESYSTEM/!wxUSE_FILESYSTEM
+  {
     wxLogVerbose(_("catalog file for domain '%s' not found."), szName);
     wxLogTrace(TRACE_I18N, _T("Catalog \"%s.mo\" not found"), szName);
     return false;
   }
 
-  // open file
+  // open file and read its data
   wxLogVerbose(_("using catalog '%s' from '%s'."), szName, strFullName.c_str());
   wxLogTrace(TRACE_I18N, _T("Using catalog \"%s\"."), strFullName.c_str());
 
+#if wxUSE_FILESYSTEM
+  wxFSFile * const fileMsg = fileSys.OpenFile(strFullName);
+  if ( !fileMsg )
+    return false;
+
+  wxInputStream *fileStream = fileMsg->GetStream();
+  m_data.SetDataLen(0);
+
+  static const size_t chunkSize = 4096;
+  while ( !fileStream->Eof() ) {
+    fileStream->Read(m_data.GetAppendBuf(chunkSize), chunkSize);
+    m_data.UngetAppendBuf(fileStream->LastRead());
+  }
+
+  delete fileMsg;
+#else // !wxUSE_FILESYSTEM
   wxFile fileMsg(strFullName);
   if ( !fileMsg.IsOpened() )
     return false;
@@ -1165,16 +1194,15 @@ bool wxMsgCatalogFile::Load(const wxString& szDirPrefix, const wxString& szName,
   wxASSERT_MSG( nSize == lenFile + size_t(0), _T("message catalog bigger than 4GB?") );
 
   // read the whole file in memory
-  m_pData = new size_t8[nSize];
-  if ( fileMsg.Read(m_pData, nSize) != lenFile ) {
-    wxDELETEA(m_pData);
+  if ( fileMsg.Read(m_data.GetWriteBuf(nSize), nSize) != lenFile )
     return false;
-  }
+#endif // wxUSE_FILESYSTEM/!wxUSE_FILESYSTEM
+
 
   // examine header
-  bool bValid = nSize + (size_t)0 > sizeof(wxMsgCatalogHeader);
+  bool bValid = m_data.GetDataLen() > sizeof(wxMsgCatalogHeader);
 
-  wxMsgCatalogHeader *pHeader = (wxMsgCatalogHeader *)m_pData;
+  const wxMsgCatalogHeader *pHeader = (wxMsgCatalogHeader *)m_data.GetData();
   if ( bValid ) {
     // we'll have to swap all the integers if it's true
     m_bSwapped = pHeader->magic == MSGCATALOG_MAGIC_SW;
@@ -1187,17 +1215,15 @@ bool wxMsgCatalogFile::Load(const wxString& szDirPrefix, const wxString& szName,
     // it's either too short or has incorrect magic number
     wxLogWarning(_("'%s' is not a valid message catalog."), strFullName.c_str());
 
-    wxDELETEA(m_pData);
     return false;
   }
 
   // initialize
   m_numStrings  = Swap(pHeader->numStrings);
-  m_pOrigTable  = (wxMsgTableEntry *)(m_pData +
+  m_pOrigTable  = (wxMsgTableEntry *)(StringData() +
                    Swap(pHeader->ofsOrigTable));
-  m_pTransTable = (wxMsgTableEntry *)(m_pData +
+  m_pTransTable = (wxMsgTableEntry *)(StringData() +
                    Swap(pHeader->ofsTransTable));
-  m_nSize = (size_t32)nSize;
 
   // now parse catalog's header and try to extract catalog charset and
   // plural forms formula from it:
@@ -1602,7 +1628,7 @@ bool wxLocale::Init(const wxString& name,
 #if defined(__UNIX__) && wxUSE_UNICODE && !defined(__WXMAC__)
 static const char *wxSetlocaleTryUTF8(int c, const wxString& lc)
 {
-    const char *l;
+    const char *l = NULL;
 
     // NB: We prefer to set UTF-8 locale if it's possible and only fall back to
     //     non-UTF-8 locale if it fails
@@ -1642,6 +1668,8 @@ static const char *wxSetlocaleTryUTF8(int c, const wxString& lc)
 
 bool wxLocale::Init(int language, int flags)
 {
+    bool ret = true;
+
     int lang = language;
     if (lang == wxLANGUAGE_DEFAULT)
     {
@@ -1729,10 +1757,7 @@ bool wxLocale::Init(int language, int flags)
     }
 
     if ( !retloc )
-    {
-        wxLogError(wxT("Cannot set locale to '%s'."), locale.c_str());
-        return false;
-    }
+        ret = false;
 
 #ifdef __AIX__
     // at least in AIX 5.2 libc is buggy and the string returned from
@@ -1742,7 +1767,7 @@ bool wxLocale::Init(int language, int flags)
     //
     // this contradicts IBM own docs but this is not of much help, so just work
     // around it in the crudest possible manner
-    char *p = wxStrchr(retloc, ' ');
+    char* p = const_cast<char*>(wxStrchr(retloc, ' '));
     if ( p )
         *p = '\0';
 #endif // __AIX__
@@ -1798,8 +1823,7 @@ bool wxLocale::Init(int language, int flags)
             if (locale.empty())
             {
                 wxLogLastError(wxT("SetThreadLocale"));
-                wxLogError(wxT("Cannot set locale to language %s."), name.c_str());
-                return false;
+                ret = false;
             }
             else
             {
@@ -1839,10 +1863,7 @@ bool wxLocale::Init(int language, int flags)
     }
 
     if ( !retloc )
-    {
-        wxLogError(wxT("Cannot set locale to language %s."), name.c_str());
-        return false;
-    }
+        ret = false;
 #elif defined(__WXMAC__)
     if (lang == wxLANGUAGE_DEFAULT)
         locale = wxEmptyString;
@@ -1856,11 +1877,6 @@ bool wxLocale::Init(int language, int flags)
         // Some C libraries don't like xx_YY form and require xx only
         retloc = wxSetlocale(LC_ALL, locale.Mid(0,2));
     }
-    if ( !retloc )
-    {
-        wxLogError(wxT("Cannot set locale to '%s'."), locale.c_str());
-        return false;
-    }
 #else
     wxUnusedVar(flags);
     return false;
@@ -1868,9 +1884,20 @@ bool wxLocale::Init(int language, int flags)
 #endif
 
 #ifndef WX_NO_LOCALE_SUPPORT
-    bool ret = Init(name, canonical, retloc,
-                    (flags & wxLOCALE_LOAD_DEFAULT) != 0,
-                    (flags & wxLOCALE_CONV_ENCODING) != 0);
+    if ( !ret )
+    {
+        wxLogWarning(_("Cannot set locale to language \"%s\"."), name.c_str());
+
+        // continue nevertheless and try to load at least the translations for
+        // this language
+    }
+
+    if ( !Init(name, canonical, retloc,
+               (flags & wxLOCALE_LOAD_DEFAULT) != 0,
+               (flags & wxLOCALE_CONV_ENCODING) != 0) )
+    {
+        ret = false;
+    }
 
     if (IsOk()) // setlocale() succeeded
         m_language = lang;
@@ -2445,11 +2472,7 @@ wxFontEncoding wxLocale::GetSystemEncoding()
     }
 #elif defined(__WXMAC__)
     TextEncoding encoding = 0 ;
-#if TARGET_CARBON
     encoding = CFStringGetSystemEncoding() ;
-#else
-    UpgradeScriptInfoToTextEncoding ( smSystemScript , kTextLanguageDontCare , kTextRegionDontCare , NULL , &encoding ) ;
-#endif
     return wxMacGetFontEncFromSystemEnc( encoding ) ;
 #elif defined(__UNIX_LIKE__) && wxUSE_FONTMAP
     const wxString encname = GetSystemEncodingName();
@@ -2833,7 +2856,7 @@ bool wxLocale::AddCatalog(const wxString& szDomain,
 // accessors for locale-dependent data
 // ----------------------------------------------------------------------------
 
-#ifdef __WXMSW__
+#if defined(__WXMSW__)
 
 /* static */
 wxString wxLocale::GetInfo(wxLocaleInfo index, wxLocaleCategory WXUNUSED(cat))
@@ -2873,7 +2896,33 @@ wxString wxLocale::GetInfo(wxLocaleInfo index, wxLocaleCategory WXUNUSED(cat))
     return str;
 }
 
-#else // !__WXMSW__
+#elif defined(__WXOSX__)
+
+/* static */
+wxString wxLocale::GetInfo(wxLocaleInfo index, wxLocaleCategory WXUNUSED(cat))
+{
+    wxCFRef<CFLocaleRef> userLocaleRef(CFLocaleCopyCurrent());
+    CFTypeRef cfstr;
+    switch ( index )
+    {
+        case wxLOCALE_THOUSANDS_SEP:
+            cfstr = CFLocaleGetValue(userLocaleRef, kCFLocaleGroupingSeparator);
+            break;
+
+        case wxLOCALE_DECIMAL_POINT:
+            cfstr = CFLocaleGetValue(userLocaleRef, kCFLocaleDecimalSeparator);
+            break;
+
+        default:
+            wxFAIL_MSG( "Unknown locale info" );
+    }
+
+    wxMacCFStringHolder
+        str(CFStringCreateCopy(NULL, static_cast<CFStringRef>(cfstr)));
+    return str.AsString();
+}
+
+#else // !__WXMSW__ && !__WXMAC__
 
 /* static */
 wxString wxLocale::GetInfo(wxLocaleInfo index, wxLocaleCategory cat)
@@ -2910,7 +2959,7 @@ wxString wxLocale::GetInfo(wxLocaleInfo index, wxLocaleCategory cat)
     }
 }
 
-#endif // __WXMSW__/!__WXMSW__
+#endif // platform
 
 // ----------------------------------------------------------------------------
 // global functions and variables