diff --git a/interface/wx/numformatter.h b/interface/wx/numformatter.h
index 1479bae1c4..42c260609f 100644
--- a/interface/wx/numformatter.h
+++ b/interface/wx/numformatter.h
@@ -8,11 +8,15 @@
/**
@class wxNumberFormatter
- Helper class for formatting and parsing numbers with thousands separators.
+ Formatting and parsing numbers using the current UI locale conventions,
+ including support for using the correct decimal point character and
+ thousands separators.
This class contains only static functions, so users must not create instances
but directly call the member functions.
+ @see wxUILocale
+
@since 2.9.2
@library{wxbase}
@@ -32,7 +36,7 @@ public:
/**
If this flag is given, thousands separators will be inserted in the
- number string representation as defined by the current locale.
+ number string representation as defined by the current UI locale.
*/
Style_WithThousandsSep = 0x01,
@@ -56,7 +60,7 @@ public:
Returns string representation of an integer number.
By default, the string will use thousands separators if appropriate for
- the current locale. This can be avoided by passing Style_None as @a
+ the current UI locale. This can be avoided by passing Style_None as @a
flags in which case the call to the function has exactly the same
effect as wxString::Format("%ld", val)
.
@@ -94,7 +98,7 @@ public:
Parse a string representation of a number possibly including thousands
separators.
- These functions parse number representation in the current locale. On
+ These functions parse number representation in the current UI locale. On
success they return @true and store the result at the location pointed
to by @a val (which can't be @NULL), otherwise @false is returned.
@@ -114,7 +118,7 @@ public:
//@}
/**
- Get the decimal separator for the current locale.
+ Get the decimal separator for the current UI locale.
Decimal separators is always defined and we fall back to returning '.'
in case of an error.
@@ -123,14 +127,14 @@ public:
/**
Get the thousands separator if grouping of the digits is used by the
- current locale.
+ current UI locale.
The value returned in @a sep should be only used if the function
returns @true, otherwise no thousands separator should be used at all.
@param sep
Points to the variable receiving the thousands separator character
- if it is used by the current locale. May be @NULL if only the
+ if it is used by the current UI locale. May be @NULL if only the
function return value is needed.
*/
static bool GetThousandsSeparatorIfUsed(wxChar *sep);
diff --git a/src/common/numformatter.cpp b/src/common/numformatter.cpp
index e57ab02335..c7fdd5d012 100644
--- a/src/common/numformatter.cpp
+++ b/src/common/numformatter.cpp
@@ -16,84 +16,7 @@
#include "wx/numformatter.h"
-#include "wx/intl.h"
-
-#include // for setlocale and LC_ALL
-
-// ----------------------------------------------------------------------------
-// local helpers
-// ----------------------------------------------------------------------------
-
-namespace
-{
-
-// Contains information about the locale which was used to initialize our
-// cached values of the decimal and thousands separators. Notice that it isn't
-// enough to store just wxLocale because the user code may call setlocale()
-// directly and storing just C locale string is not enough because we can use
-// the OS API directly instead of the CRT ones on some platforms. So just store
-// both.
-class LocaleId
-{
-public:
- LocaleId()
- {
-#if wxUSE_INTL
- m_wxloc = NULL;
-#endif // wxUSE_INTL
- m_cloc = NULL;
- }
-
- ~LocaleId()
- {
- Free();
- }
-
-#if wxUSE_INTL
- // Return true if this is the first time this function is called for this
- // object or if the program locale has changed since the last time it was
- // called. Otherwise just return false indicating that updating locale-
- // dependent information is not necessary.
- bool NotInitializedOrHasChanged()
- {
- wxLocale * const wxloc = wxGetLocale();
- const char * const cloc = setlocale(LC_ALL, NULL);
- if ( m_wxloc || m_cloc )
- {
- if ( m_wxloc == wxloc && strcmp(m_cloc, cloc) == 0 )
- return false;
-
- Free();
- }
- //else: Not initialized yet.
-
- m_wxloc = wxloc;
- m_cloc = wxCRT_StrdupA(cloc);
-
- return true;
- }
-#endif // wxUSE_INTL
-
-private:
- void Free()
- {
-#if wxUSE_INTL
- free(m_cloc);
-#endif // wxUSE_INTL
- }
-
-#if wxUSE_INTL
- // Non-owned pointer to wxLocale which was used.
- wxLocale *m_wxloc;
-#endif // wxUSE_INTL
-
- // Owned pointer to the C locale string.
- char *m_cloc;
-
- wxDECLARE_NO_COPY_CLASS(LocaleId);
-};
-
-} // anonymous namespace
+#include "wx/uilocale.h"
// ============================================================================
// wxNumberFormatter implementation
@@ -111,14 +34,10 @@ wxChar wxNumberFormatter::GetDecimalSeparator()
// concurrently from more than one thread so it's not a real problem.
static wxChar s_decimalSeparator = 0;
- // Remember the locale which was current when we initialized, we must redo
- // the initialization if the locale changed.
- static LocaleId s_localeUsedForInit;
-
- if ( s_localeUsedForInit.NotInitializedOrHasChanged() )
+ if ( !s_decimalSeparator )
{
const wxString
- s = wxLocale::GetInfo(wxLOCALE_DECIMAL_POINT, wxLOCALE_CAT_NUMBER);
+ s = wxUILocale::GetCurrent().GetInfo(wxLOCALE_DECIMAL_POINT, wxLOCALE_CAT_NUMBER);
if ( s.length() == 1 )
{
s_decimalSeparator = s[0];
@@ -141,12 +60,14 @@ bool wxNumberFormatter::GetThousandsSeparatorIfUsed(wxChar *sep)
{
#if wxUSE_INTL
static wxChar s_thousandsSeparator = 0;
- static LocaleId s_localeUsedForInit;
+ static bool s_thousandsSeparatorInitialized = false;
- if ( s_localeUsedForInit.NotInitializedOrHasChanged() )
+ if ( !s_thousandsSeparatorInitialized )
{
+ s_thousandsSeparatorInitialized = true;
+
const wxString
- s = wxLocale::GetInfo(wxLOCALE_THOUSANDS_SEP, wxLOCALE_CAT_NUMBER);
+ s = wxUILocale::GetCurrent().GetInfo(wxLOCALE_THOUSANDS_SEP, wxLOCALE_CAT_NUMBER);
if ( s.length() == 1 )
{
s_thousandsSeparator = s[0];
@@ -172,6 +93,21 @@ bool wxNumberFormatter::GetThousandsSeparatorIfUsed(wxChar *sep)
// Conversion to string and helpers
// ----------------------------------------------------------------------------
+namespace
+{
+
+void ReplaceSeparatorIfNecessary(wxString& s, wxChar sepOld, wxChar sepNew)
+{
+ if ( sepNew != sepOld )
+ {
+ const size_t posSep = s.find(sepOld);
+ if ( posSep != wxString::npos )
+ s[posSep] = sepNew;
+ }
+}
+
+} // anonymous namespace
+
wxString wxNumberFormatter::PostProcessIntString(wxString s, int style)
{
if ( style & Style_WithThousandsSep )
@@ -206,7 +142,9 @@ wxString wxNumberFormatter::ToString(wxULongLong_t val, int style)
wxString wxNumberFormatter::ToString(double val, int precision, int style)
{
- wxString s = wxString::FromDouble(val,precision);
+ wxString s = wxString::FromCDouble(val,precision);
+
+ ReplaceSeparatorIfNecessary(s, '.', GetDecimalSeparator());
if ( style & Style_WithThousandsSep )
AddThousandsSeparators(s);
@@ -330,5 +268,6 @@ bool wxNumberFormatter::FromString(wxString s, wxULongLong_t *val)
bool wxNumberFormatter::FromString(wxString s, double *val)
{
RemoveThousandsSeparators(s);
- return s.ToDouble(val);
+ ReplaceSeparatorIfNecessary(s, GetDecimalSeparator(), '.');
+ return s.ToCDouble(val);
}