]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/intl.cpp
Forbid creation of wxStandardPaths object directly.
[wxWidgets.git] / src / common / intl.cpp
index 40d6fa1db5b73720507786742641b009962b7fa1..16bdbd45639c1527175f4b248354fab23218f77c 100644 (file)
@@ -121,7 +121,7 @@ inline wxString ExtractNotLang(const wxString& langFull)
 // wxLanguageInfo
 // ----------------------------------------------------------------------------
 
-#ifdef __WXMSW__
+#ifdef __WINDOWS__
 
 // helper used by wxLanguageInfo::GetLocaleName() and elsewhere to determine
 // whether the locale is Unicode-only (it is if this function returns empty
@@ -177,7 +177,7 @@ wxString wxLanguageInfo::GetLocaleName() const
     return locale;
 }
 
-#endif // __WXMSW__
+#endif // __WINDOWS__
 
 // ----------------------------------------------------------------------------
 // wxLocale
@@ -206,7 +206,11 @@ wxLanguageInfoArray *wxLocale::ms_languagesDB = NULL;
 
 void wxLocale::DoCommonInit()
 {
-    m_pszOldLocale = NULL;
+    // Store the current locale in order to be able to restore it in the dtor.
+    m_pszOldLocale = wxSetlocale(LC_ALL, NULL);
+    if ( m_pszOldLocale )
+        m_pszOldLocale = wxStrdup(m_pszOldLocale);
+
 
     m_pOldLocale = wxSetLocale(this);
 
@@ -285,13 +289,7 @@ bool wxLocale::DoInit(const wxString& name,
                     wxS("no locale to set in wxLocale::Init()") );
     }
 
-    const char *oldLocale = wxSetlocale(LC_ALL, szLocale);
-    if ( oldLocale )
-        m_pszOldLocale = wxStrdup(oldLocale);
-    else
-        m_pszOldLocale = NULL;
-
-    if ( m_pszOldLocale == NULL )
+    if ( !wxSetlocale(LC_ALL, szLocale) )
     {
         wxLogError(_("locale '%s' cannot be set."), szLocale);
     }
@@ -570,6 +568,18 @@ bool wxLocale::Init(int language, int flags)
 #endif // !WX_NO_LOCALE_SUPPORT
 }
 
+namespace
+{
+
+// Small helper function: get the value of the given environment variable and
+// return true only if the variable was found and has non-empty value.
+inline bool wxGetNonEmptyEnvVar(const wxString& name, wxString* value)
+{
+    return wxGetEnv(name, value) && !value->empty();
+}
+
+} // anonymous namespace
+
 /*static*/ int wxLocale::GetSystemLanguage()
 {
     CreateLanguagesDB();
@@ -592,9 +602,9 @@ bool wxLocale::Init(int language, int flags)
     str.reset(wxCFRetain((CFStringRef)CFLocaleGetValue(userLocaleRef, kCFLocaleCountryCode)));
     langFull += str.AsString();
 #else
-    if (!wxGetEnv(wxS("LC_ALL"), &langFull) &&
-        !wxGetEnv(wxS("LC_MESSAGES"), &langFull) &&
-        !wxGetEnv(wxS("LANG"), &langFull))
+    if (!wxGetNonEmptyEnvVar(wxS("LC_ALL"), &langFull) &&
+        !wxGetNonEmptyEnvVar(wxS("LC_MESSAGES"), &langFull) &&
+        !wxGetNonEmptyEnvVar(wxS("LANG"), &langFull))
     {
         // no language specified, treat it as English
         return wxLANGUAGE_ENGLISH_US;
@@ -781,8 +791,9 @@ wxString wxLocale::GetSystemEncodingName()
     UINT codepage = ::GetACP();
     encname.Printf(wxS("windows-%u"), codepage);
 #elif defined(__WXMAC__)
-    // default is just empty string, this resolves to the default system
-    // encoding later
+    encname = wxCFStringRef::AsString(
+                CFStringGetNameOfEncoding(CFStringGetSystemEncoding())
+              );
 #elif defined(__UNIX_LIKE__)
 
 #if defined(HAVE_LANGINFO_H) && defined(CODESET)
@@ -1126,7 +1137,7 @@ wxString wxLocale::GetHeaderValue(const wxString& header,
 // accessors for locale-dependent data
 // ----------------------------------------------------------------------------
 
-#if defined(__WXMSW__) || defined(__WXOSX__)
+#if defined(__WINDOWS__) || defined(__WXOSX__)
 
 namespace
 {
@@ -1148,7 +1159,7 @@ static wxString TranslateFromUnicodeFormat(const wxString& fmt)
 
     const char* formatchars =
         "dghHmMsSy"
-#ifdef __WXMSW__
+#ifdef __WINDOWS__
         "t"
 #else
         "EawD"
@@ -1188,7 +1199,7 @@ static wxString TranslateFromUnicodeFormat(const wxString& fmt)
                             // between 1 and 2 digits for days
                             fmtWX += "%d";
                             break;
-#ifdef __WXMSW__
+#ifdef __WINDOWS__
                         case 3: // ddd
                             fmtWX += "%a";
                             break;
@@ -1201,7 +1212,7 @@ static wxString TranslateFromUnicodeFormat(const wxString& fmt)
                             wxFAIL_MSG( "too many 'd's" );
                     }
                     break;
-#ifndef __WXMSW__
+#ifndef __WINDOWS__
                 case 'D':
                     switch ( lastCount )
                     {
@@ -1344,12 +1355,12 @@ static wxString TranslateFromUnicodeFormat(const wxString& fmt)
                     wxASSERT_MSG( lastCount <= 2, "too many 'g's" );
 
                     break;
-#ifndef __WXMSW__
+#ifndef __WINDOWS__
                 case 'a':
                     fmtWX += "%p";
                     break;
 #endif
-#ifdef __WXMSW__
+#ifdef __WINDOWS__
                 case 't':
                     switch ( lastCount )
                     {
@@ -1389,9 +1400,9 @@ static wxString TranslateFromUnicodeFormat(const wxString& fmt)
 
 } // anonymous namespace
 
-#endif // __WXMSW__ || __WXOSX__
+#endif // __WINDOWS__ || __WXOSX__
 
-#if defined(__WXMSW__)
+#if defined(__WINDOWS__)
 
 namespace
 {
@@ -1421,15 +1432,54 @@ LCTYPE GetLCTYPEFormatFromLocalInfo(wxLocaleInfo index)
 /* static */
 wxString wxLocale::GetInfo(wxLocaleInfo index, wxLocaleCategory cat)
 {
-    wxUint32 lcid = LOCALE_USER_DEFAULT;
-    if ( wxGetLocale() )
+    const wxLanguageInfo * const
+        info = wxGetLocale() ? GetLanguageInfo(wxGetLocale()->GetLanguage())
+                             : NULL;
+    if ( !info )
     {
-        const wxLanguageInfo * const
-            info = GetLanguageInfo(wxGetLocale()->GetLanguage());
-        if ( info )
-            lcid = info->GetLCID();
+        // wxSetLocale() hadn't been called yet of failed, hence CRT must be
+        // using "C" locale -- but check it to detect bugs that would happen if
+        // this were not the case.
+        wxASSERT_MSG( strcmp(setlocale(LC_ALL, NULL), "C") == 0,
+                      wxS("You probably called setlocale() directly instead ")
+                      wxS("of using wxLocale and now there is a ")
+                      wxS("mismatch between C/C++ and Windows locale.\n")
+                      wxS("Things are going to break, please only change ")
+                      wxS("locale by creating wxLocale objects to avoid this!") );
+
+
+        // Return the hard coded values for C locale. This is really the right
+        // thing to do as there is no LCID we can use in the code below in this
+        // case, even LOCALE_INVARIANT is not quite the same as C locale (the
+        // only difference is that it uses %Y instead of %y in the date format
+        // but this difference is significant enough).
+        switch ( index )
+        {
+            case wxLOCALE_THOUSANDS_SEP:
+                return wxString();
+
+            case wxLOCALE_DECIMAL_POINT:
+                return ".";
+
+            case wxLOCALE_SHORT_DATE_FMT:
+                return "%m/%d/%y";
+
+            case wxLOCALE_LONG_DATE_FMT:
+                return "%A, %B %d, %Y";
+
+            case wxLOCALE_TIME_FMT:
+                return "%H:%M:%S";
+
+            case wxLOCALE_DATE_TIME_FMT:
+                return "%m/%d/%y %H:%M:%S";
+
+            default:
+                wxFAIL_MSG( "unknown wxLocaleInfo" );
+        }
     }
 
+    const wxUint32 lcid = info->GetLCID();
+
     wxString str;
 
     wxChar buf[256];
@@ -1582,7 +1632,7 @@ wxString wxLocale::GetInfo(wxLocaleInfo index, wxLocaleCategory WXUNUSED(cat))
     return str.AsString();
 }
 
-#else // !__WXMSW__ && !__WXOSX__, assume generic POSIX
+#else // !__WINDOWS__ && !__WXOSX__, assume generic POSIX
 
 namespace
 {