From 3fc031e75b0fef994d3562bc653c5982477adf66 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 14 Aug 2021 13:59:17 +0100 Subject: [PATCH] Add wxNumberFormatter::Format() for floating point numbers The existing ToString() is not flexible enough to be used in wxGrid, which supports specifying the width (and not just the precision) as well as using formats other than "%g" and "%f" which are the only ones supported by the existing function. Note that currently the implementation simply calls wxString::Format() and then adjusts the decimal separator, but it could, in principle, use wxUILocale methods for formatting the floating point numbers using native platform functions for doing this, e.g. CFNumberFormatter under macOS. --- include/wx/numformatter.h | 7 +++++++ interface/wx/numformatter.h | 10 ++++++++++ src/common/numformatter.cpp | 17 +++++++++++++++++ 3 files changed, 34 insertions(+) diff --git a/include/wx/numformatter.h b/include/wx/numformatter.h index 24ab702ab7..5e0f795dbe 100644 --- a/include/wx/numformatter.h +++ b/include/wx/numformatter.h @@ -40,6 +40,13 @@ public: int precision, int style = Style_WithThousandsSep); + // Format the given number using one of the floating point formats and + // ensure that the result uses the correct decimal separator. + // Prefer using ToString() if possible, i.e. if format is "%g" or "%.Nf" + // which are supported by it directly. + static wxString Format(const wxString& format, double val); + + // Parse a string representing a number, possibly with thousands separator. // // Return true on success and stores the result in the provided location diff --git a/interface/wx/numformatter.h b/interface/wx/numformatter.h index 42c260609f..f635e2327d 100644 --- a/interface/wx/numformatter.h +++ b/interface/wx/numformatter.h @@ -93,6 +93,16 @@ public: static wxString ToString(double val, int precision, int flags = Style_WithThousandsSep); + /** + Format the given number using one of the floating point formats and + ensure that the result uses the correct decimal separator. + + Prefer using ToString() if possible, i.e. if format is "%g" or "%.Nf" + which are supported by it directly. + + @since 3.1.6 + */ + static wxString Format(const wxString& format, double val); /** Parse a string representation of a number possibly including thousands diff --git a/src/common/numformatter.cpp b/src/common/numformatter.cpp index c7fdd5d012..c59ea520db 100644 --- a/src/common/numformatter.cpp +++ b/src/common/numformatter.cpp @@ -155,6 +155,23 @@ wxString wxNumberFormatter::ToString(double val, int precision, int style) return s; } +wxString wxNumberFormatter::Format(const wxString& format, double val) +{ + wxString s = wxString::Format(format, val); + + const wxChar sep = GetDecimalSeparator(); + if ( s.find(sep) == wxString::npos ) + { + const wxChar other = sep == '.' ? ',' : '.'; + const size_t posSep = s.find(other); + if ( posSep != wxString::npos ) + s[posSep] = sep; + } + //else: it already uses the correct separator + + return s; +} + void wxNumberFormatter::AddThousandsSeparators(wxString& s) { // Thousands separators for numbers in scientific format are not relevant.