diff --git a/include/wx/intl.h b/include/wx/intl.h index fea4d2d65b..c2020ddbfc 100644 --- a/include/wx/intl.h +++ b/include/wx/intl.h @@ -214,6 +214,17 @@ public: static wxString GetInfo(wxLocaleInfo index, wxLocaleCategory cat = wxLOCALE_CAT_DEFAULT); + // Same as GetInfo() but uses current locale at the OS level to retrieve + // the information. Normally it should be the same as the one used by + // GetInfo() but there are two exceptions: the most important one is that + // if no locale had been set, GetInfo() would fall back to "C" locale, + // while this one uses the default OS locale. Another, more rare, one is + // that some locales might not supported by the OS. + // + // Currently this is the same as GetInfo() under non-MSW platforms. + static wxString GetOSInfo(wxLocaleInfo index, + wxLocaleCategory cat = wxLOCALE_CAT_DEFAULT); + // return true if the locale was set successfully bool IsOk() const { return m_pszOldLocale != NULL; } diff --git a/interface/wx/intl.h b/interface/wx/intl.h index ea20a8eff0..ba32b7e348 100644 --- a/interface/wx/intl.h +++ b/interface/wx/intl.h @@ -421,6 +421,21 @@ public: static wxString GetInfo(wxLocaleInfo index, wxLocaleCategory cat = wxLOCALE_CAT_DEFAULT); + /** + Get the values of a locale datum in the OS locale. + + This function is similar to GetInfo() and, in fact, identical to it + under non-MSW systems. Under MSW it differs from it when no locale had + been explicitly set: GetInfo() returns the values corresponding to the + "C" locale used by the standard library functions, while this method + returns the values used by the OS which, in Windows case, correspond to + the user settings in the control panel. + + @since 3.1.0 + */ + static wxString GetOSInfo(wxLocaleInfo index, + wxLocaleCategory cat = wxLOCALE_CAT_DEFAULT); + /** Initializes the wxLocale instance. diff --git a/src/common/intl.cpp b/src/common/intl.cpp index 411680e30e..f25bc8849e 100644 --- a/src/common/intl.cpp +++ b/src/common/intl.cpp @@ -1420,59 +1420,11 @@ LCTYPE GetLCTYPEFormatFromLocalInfo(wxLocaleInfo index) return 0; } -} // anonymous namespace - -/* static */ -wxString wxLocale::GetInfo(wxLocaleInfo index, wxLocaleCategory cat) +wxString +GetInfoFromLCID(LCID lcid, + wxLocaleInfo index, + wxLocaleCategory cat = wxLOCALE_CAT_DEFAULT) { - const wxLanguageInfo * const - info = wxGetLocale() ? GetLanguageInfo(wxGetLocale()->GetLanguage()) - : NULL; - if ( !info ) - { - // 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]; @@ -1529,11 +1481,13 @@ wxString wxLocale::GetInfo(wxLocaleInfo index, wxLocaleCategory cat) // ("%#c" uses long date but we have no way to specify the // alternate representation here) { - const wxString datefmt = GetInfo(wxLOCALE_SHORT_DATE_FMT); + const wxString + datefmt = GetInfoFromLCID(lcid, wxLOCALE_SHORT_DATE_FMT); if ( datefmt.empty() ) break; - const wxString timefmt = GetInfo(wxLOCALE_TIME_FMT); + const wxString + timefmt = GetInfoFromLCID(lcid, wxLOCALE_TIME_FMT); if ( timefmt.empty() ) break; @@ -1548,6 +1502,66 @@ wxString wxLocale::GetInfo(wxLocaleInfo index, wxLocaleCategory cat) return str; } +} // anonymous namespace + +/* static */ +wxString wxLocale::GetInfo(wxLocaleInfo index, wxLocaleCategory cat) +{ + const wxLanguageInfo * const + info = wxGetLocale() ? GetLanguageInfo(wxGetLocale()->GetLanguage()) + : NULL; + if ( !info ) + { + // 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" ); + } + } + + return GetInfoFromLCID(info->GetLCID(), index, cat); +} + +/* static */ +wxString wxLocale::GetOSInfo(wxLocaleInfo index, wxLocaleCategory cat) +{ + return GetInfoFromLCID(::GetThreadLocale(), index, cat); +} + #elif defined(__WXOSX__) /* static */ @@ -1762,6 +1776,16 @@ wxString wxLocale::GetInfo(wxLocaleInfo index, wxLocaleCategory cat) #endif // platform +#ifndef __WINDOWS__ + +/* static */ +wxString wxLocale::GetOSInfo(wxLocaleInfo index, wxLocaleCategory cat) +{ + return GetInfo(index, cat); +} + +#endif // !__WINDOWS__ + // ---------------------------------------------------------------------------- // global functions and variables // ---------------------------------------------------------------------------- diff --git a/src/msw/datetimectrl.cpp b/src/msw/datetimectrl.cpp index b7619fd7f2..83cca78f1f 100644 --- a/src/msw/datetimectrl.cpp +++ b/src/msw/datetimectrl.cpp @@ -112,7 +112,7 @@ wxSize wxDateTimePickerCtrl::DoGetBestSize() const // Use the same native format as the underlying native control. #if wxUSE_INTL - wxString s = wxDateTime::Now().Format(wxLocale::GetInfo(MSWGetFormat())); + wxString s = wxDateTime::Now().Format(wxLocale::GetOSInfo(MSWGetFormat())); #else // !wxUSE_INTL wxString s("XXX-YYY-ZZZZ"); #endif // wxUSE_INTL/!wxUSE_INTL