From 6686fbad16ec929f33cbbcc1b638bf00406218c5 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 19 Jan 2011 10:47:40 +0000 Subject: [PATCH] Add wxNumberFormatter class helping to deal with thousands separators. wxNumberFormatter formats and parses numbers with thousands separators. Add the class itself as well as documentation and the unit test for it. See #12166. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@66710 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- Makefile.in | 19 +++ build/bakefiles/files.bkl | 2 + build/msw/makefile.bcc | 16 +++ build/msw/makefile.gcc | 16 +++ build/msw/makefile.vc | 16 +++ build/msw/makefile.wat | 16 +++ build/msw/wx_base.dsp | 12 ++ build/msw/wx_core.dsp | 4 + build/msw/wx_vc7_base.vcproj | 9 ++ build/msw/wx_vc7_core.vcproj | 3 + build/msw/wx_vc8_base.vcproj | 12 ++ build/msw/wx_vc8_core.vcproj | 4 + build/msw/wx_vc9_base.vcproj | 12 ++ build/msw/wx_vc9_core.vcproj | 4 + docs/changes.txt | 1 + include/wx/numformatter.h | 69 ++++++++++ interface/wx/numformatter.h | 126 +++++++++++++++++ interface/wx/string.h | 17 ++- src/common/numformatter.cpp | 190 ++++++++++++++++++++++++++ tests/Makefile.in | 4 + tests/makefile.bcc | 4 + tests/makefile.gcc | 4 + tests/makefile.vc | 4 + tests/makefile.wat | 4 + tests/strings/numformatter.cpp | 239 +++++++++++++++++++++++++++++++++ tests/test.bkl | 1 + tests/test_test.dsp | 4 + tests/test_vc7_test.vcproj | 3 + tests/test_vc8_test.vcproj | 4 + tests/test_vc9_test.vcproj | 4 + wxGTK.spec | 1 + wxMotif.spec | 1 + wxX11.spec | 1 + 33 files changed, 822 insertions(+), 4 deletions(-) create mode 100644 include/wx/numformatter.h create mode 100644 interface/wx/numformatter.h create mode 100644 src/common/numformatter.cpp create mode 100644 tests/strings/numformatter.cpp diff --git a/Makefile.in b/Makefile.in index 3970e2012e..74c5e06f2b 100644 --- a/Makefile.in +++ b/Makefile.in @@ -403,6 +403,7 @@ ALL_BASE_HEADERS = \ wx/msgout.h \ wx/msgqueue.h \ wx/mstream.h \ + wx/numformatter.h \ wx/object.h \ wx/platform.h \ wx/platinfo.h \ @@ -580,6 +581,7 @@ ALL_PORTS_BASE_HEADERS = \ wx/msgout.h \ wx/msgqueue.h \ wx/mstream.h \ + wx/numformatter.h \ wx/object.h \ wx/platform.h \ wx/platinfo.h \ @@ -761,6 +763,7 @@ ALL_BASE_SOURCES = \ src/common/mimecmn.cpp \ src/common/module.cpp \ src/common/mstream.cpp \ + src/common/numformatter.cpp \ src/common/object.cpp \ src/common/platinfo.cpp \ src/common/powercmn.cpp \ @@ -959,6 +962,7 @@ MONODLL_OBJECTS = \ monodll_mimecmn.o \ monodll_module.o \ monodll_mstream.o \ + monodll_numformatter.o \ monodll_object.o \ monodll_platinfo.o \ monodll_powercmn.o \ @@ -1091,6 +1095,7 @@ MONOLIB_OBJECTS = \ monolib_mimecmn.o \ monolib_module.o \ monolib_mstream.o \ + monolib_numformatter.o \ monolib_object.o \ monolib_platinfo.o \ monolib_powercmn.o \ @@ -1218,6 +1223,7 @@ BASEDLL_OBJECTS = \ basedll_mimecmn.o \ basedll_module.o \ basedll_mstream.o \ + basedll_numformatter.o \ basedll_object.o \ basedll_platinfo.o \ basedll_powercmn.o \ @@ -1328,6 +1334,7 @@ BASELIB_OBJECTS = \ baselib_mimecmn.o \ baselib_module.o \ baselib_mstream.o \ + baselib_numformatter.o \ baselib_object.o \ baselib_platinfo.o \ baselib_powercmn.o \ @@ -15393,6 +15400,9 @@ monodll_module.o: $(srcdir)/src/common/module.cpp $(MONODLL_ODEP) monodll_mstream.o: $(srcdir)/src/common/mstream.cpp $(MONODLL_ODEP) $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/common/mstream.cpp +monodll_numformatter.o: $(srcdir)/src/common/numformatter.cpp $(MONODLL_ODEP) + $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/common/numformatter.cpp + monodll_object.o: $(srcdir)/src/common/object.cpp $(MONODLL_ODEP) $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/common/object.cpp @@ -20670,6 +20680,9 @@ monolib_module.o: $(srcdir)/src/common/module.cpp $(MONOLIB_ODEP) monolib_mstream.o: $(srcdir)/src/common/mstream.cpp $(MONOLIB_ODEP) $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/common/mstream.cpp +monolib_numformatter.o: $(srcdir)/src/common/numformatter.cpp $(MONOLIB_ODEP) + $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/common/numformatter.cpp + monolib_object.o: $(srcdir)/src/common/object.cpp $(MONOLIB_ODEP) $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/common/object.cpp @@ -25947,6 +25960,9 @@ basedll_module.o: $(srcdir)/src/common/module.cpp $(BASEDLL_ODEP) basedll_mstream.o: $(srcdir)/src/common/mstream.cpp $(BASEDLL_ODEP) $(CXXC) -c -o $@ $(BASEDLL_CXXFLAGS) $(srcdir)/src/common/mstream.cpp +basedll_numformatter.o: $(srcdir)/src/common/numformatter.cpp $(BASEDLL_ODEP) + $(CXXC) -c -o $@ $(BASEDLL_CXXFLAGS) $(srcdir)/src/common/numformatter.cpp + basedll_object.o: $(srcdir)/src/common/object.cpp $(BASEDLL_ODEP) $(CXXC) -c -o $@ $(BASEDLL_CXXFLAGS) $(srcdir)/src/common/object.cpp @@ -26448,6 +26464,9 @@ baselib_module.o: $(srcdir)/src/common/module.cpp $(BASELIB_ODEP) baselib_mstream.o: $(srcdir)/src/common/mstream.cpp $(BASELIB_ODEP) $(CXXC) -c -o $@ $(BASELIB_CXXFLAGS) $(srcdir)/src/common/mstream.cpp +baselib_numformatter.o: $(srcdir)/src/common/numformatter.cpp $(BASELIB_ODEP) + $(CXXC) -c -o $@ $(BASELIB_CXXFLAGS) $(srcdir)/src/common/numformatter.cpp + baselib_object.o: $(srcdir)/src/common/object.cpp $(BASELIB_ODEP) $(CXXC) -c -o $@ $(BASELIB_CXXFLAGS) $(srcdir)/src/common/object.cpp diff --git a/build/bakefiles/files.bkl b/build/bakefiles/files.bkl index 29e22458dc..9d59f444d9 100644 --- a/build/bakefiles/files.bkl +++ b/build/bakefiles/files.bkl @@ -362,6 +362,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! src/common/mimecmn.cpp src/common/module.cpp src/common/mstream.cpp + src/common/numformatter.cpp src/common/object.cpp src/common/platinfo.cpp src/common/powercmn.cpp @@ -490,6 +491,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! wx/msgout.h wx/msgqueue.h wx/mstream.h + wx/numformatter.h wx/object.h wx/platform.h wx/platinfo.h diff --git a/build/msw/makefile.bcc b/build/msw/makefile.bcc index cc59e31472..ca01770400 100644 --- a/build/msw/makefile.bcc +++ b/build/msw/makefile.bcc @@ -369,6 +369,7 @@ MONODLL_OBJECTS = \ $(OBJS)\monodll_mimecmn.obj \ $(OBJS)\monodll_module.obj \ $(OBJS)\monodll_mstream.obj \ + $(OBJS)\monodll_numformatter.obj \ $(OBJS)\monodll_object.obj \ $(OBJS)\monodll_platinfo.obj \ $(OBJS)\monodll_powercmn.obj \ @@ -516,6 +517,7 @@ MONOLIB_OBJECTS = \ $(OBJS)\monolib_mimecmn.obj \ $(OBJS)\monolib_module.obj \ $(OBJS)\monolib_mstream.obj \ + $(OBJS)\monolib_numformatter.obj \ $(OBJS)\monolib_object.obj \ $(OBJS)\monolib_platinfo.obj \ $(OBJS)\monolib_powercmn.obj \ @@ -661,6 +663,7 @@ BASEDLL_OBJECTS = \ $(OBJS)\basedll_mimecmn.obj \ $(OBJS)\basedll_module.obj \ $(OBJS)\basedll_mstream.obj \ + $(OBJS)\basedll_numformatter.obj \ $(OBJS)\basedll_object.obj \ $(OBJS)\basedll_platinfo.obj \ $(OBJS)\basedll_powercmn.obj \ @@ -790,6 +793,7 @@ BASELIB_OBJECTS = \ $(OBJS)\baselib_mimecmn.obj \ $(OBJS)\baselib_module.obj \ $(OBJS)\baselib_mstream.obj \ + $(OBJS)\baselib_numformatter.obj \ $(OBJS)\baselib_object.obj \ $(OBJS)\baselib_platinfo.obj \ $(OBJS)\baselib_powercmn.obj \ @@ -6000,6 +6004,9 @@ $(OBJS)\monodll_module.obj: ..\..\src\common\module.cpp $(OBJS)\monodll_mstream.obj: ..\..\src\common\mstream.cpp $(CXX) -q -c -P -o$@ $(MONODLL_CXXFLAGS) ..\..\src\common\mstream.cpp +$(OBJS)\monodll_numformatter.obj: ..\..\src\common\numformatter.cpp + $(CXX) -q -c -P -o$@ $(MONODLL_CXXFLAGS) ..\..\src\common\numformatter.cpp + $(OBJS)\monodll_object.obj: ..\..\src\common\object.cpp $(CXX) -q -c -P -o$@ $(MONODLL_CXXFLAGS) ..\..\src\common\object.cpp @@ -8322,6 +8329,9 @@ $(OBJS)\monolib_module.obj: ..\..\src\common\module.cpp $(OBJS)\monolib_mstream.obj: ..\..\src\common\mstream.cpp $(CXX) -q -c -P -o$@ $(MONOLIB_CXXFLAGS) ..\..\src\common\mstream.cpp +$(OBJS)\monolib_numformatter.obj: ..\..\src\common\numformatter.cpp + $(CXX) -q -c -P -o$@ $(MONOLIB_CXXFLAGS) ..\..\src\common\numformatter.cpp + $(OBJS)\monolib_object.obj: ..\..\src\common\object.cpp $(CXX) -q -c -P -o$@ $(MONOLIB_CXXFLAGS) ..\..\src\common\object.cpp @@ -10644,6 +10654,9 @@ $(OBJS)\basedll_module.obj: ..\..\src\common\module.cpp $(OBJS)\basedll_mstream.obj: ..\..\src\common\mstream.cpp $(CXX) -q -c -P -o$@ $(BASEDLL_CXXFLAGS) ..\..\src\common\mstream.cpp +$(OBJS)\basedll_numformatter.obj: ..\..\src\common\numformatter.cpp + $(CXX) -q -c -P -o$@ $(BASEDLL_CXXFLAGS) ..\..\src\common\numformatter.cpp + $(OBJS)\basedll_object.obj: ..\..\src\common\object.cpp $(CXX) -q -c -P -o$@ $(BASEDLL_CXXFLAGS) ..\..\src\common\object.cpp @@ -10977,6 +10990,9 @@ $(OBJS)\baselib_module.obj: ..\..\src\common\module.cpp $(OBJS)\baselib_mstream.obj: ..\..\src\common\mstream.cpp $(CXX) -q -c -P -o$@ $(BASELIB_CXXFLAGS) ..\..\src\common\mstream.cpp +$(OBJS)\baselib_numformatter.obj: ..\..\src\common\numformatter.cpp + $(CXX) -q -c -P -o$@ $(BASELIB_CXXFLAGS) ..\..\src\common\numformatter.cpp + $(OBJS)\baselib_object.obj: ..\..\src\common\object.cpp $(CXX) -q -c -P -o$@ $(BASELIB_CXXFLAGS) ..\..\src\common\object.cpp diff --git a/build/msw/makefile.gcc b/build/msw/makefile.gcc index fda53b140a..f9d1a54671 100644 --- a/build/msw/makefile.gcc +++ b/build/msw/makefile.gcc @@ -355,6 +355,7 @@ MONODLL_OBJECTS = \ $(OBJS)\monodll_mimecmn.o \ $(OBJS)\monodll_module.o \ $(OBJS)\monodll_mstream.o \ + $(OBJS)\monodll_numformatter.o \ $(OBJS)\monodll_object.o \ $(OBJS)\monodll_platinfo.o \ $(OBJS)\monodll_powercmn.o \ @@ -503,6 +504,7 @@ MONOLIB_OBJECTS = \ $(OBJS)\monolib_mimecmn.o \ $(OBJS)\monolib_module.o \ $(OBJS)\monolib_mstream.o \ + $(OBJS)\monolib_numformatter.o \ $(OBJS)\monolib_object.o \ $(OBJS)\monolib_platinfo.o \ $(OBJS)\monolib_powercmn.o \ @@ -649,6 +651,7 @@ BASEDLL_OBJECTS = \ $(OBJS)\basedll_mimecmn.o \ $(OBJS)\basedll_module.o \ $(OBJS)\basedll_mstream.o \ + $(OBJS)\basedll_numformatter.o \ $(OBJS)\basedll_object.o \ $(OBJS)\basedll_platinfo.o \ $(OBJS)\basedll_powercmn.o \ @@ -779,6 +782,7 @@ BASELIB_OBJECTS = \ $(OBJS)\baselib_mimecmn.o \ $(OBJS)\baselib_module.o \ $(OBJS)\baselib_mstream.o \ + $(OBJS)\baselib_numformatter.o \ $(OBJS)\baselib_object.o \ $(OBJS)\baselib_platinfo.o \ $(OBJS)\baselib_powercmn.o \ @@ -6150,6 +6154,9 @@ $(OBJS)\monodll_module.o: ../../src/common/module.cpp $(OBJS)\monodll_mstream.o: ../../src/common/mstream.cpp $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< +$(OBJS)\monodll_numformatter.o: ../../src/common/numformatter.cpp + $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< + $(OBJS)\monodll_object.o: ../../src/common/object.cpp $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< @@ -8472,6 +8479,9 @@ $(OBJS)\monolib_module.o: ../../src/common/module.cpp $(OBJS)\monolib_mstream.o: ../../src/common/mstream.cpp $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< +$(OBJS)\monolib_numformatter.o: ../../src/common/numformatter.cpp + $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< + $(OBJS)\monolib_object.o: ../../src/common/object.cpp $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< @@ -10794,6 +10804,9 @@ $(OBJS)\basedll_module.o: ../../src/common/module.cpp $(OBJS)\basedll_mstream.o: ../../src/common/mstream.cpp $(CXX) -c -o $@ $(BASEDLL_CXXFLAGS) $(CPPDEPS) $< +$(OBJS)\basedll_numformatter.o: ../../src/common/numformatter.cpp + $(CXX) -c -o $@ $(BASEDLL_CXXFLAGS) $(CPPDEPS) $< + $(OBJS)\basedll_object.o: ../../src/common/object.cpp $(CXX) -c -o $@ $(BASEDLL_CXXFLAGS) $(CPPDEPS) $< @@ -11127,6 +11140,9 @@ $(OBJS)\baselib_module.o: ../../src/common/module.cpp $(OBJS)\baselib_mstream.o: ../../src/common/mstream.cpp $(CXX) -c -o $@ $(BASELIB_CXXFLAGS) $(CPPDEPS) $< +$(OBJS)\baselib_numformatter.o: ../../src/common/numformatter.cpp + $(CXX) -c -o $@ $(BASELIB_CXXFLAGS) $(CPPDEPS) $< + $(OBJS)\baselib_object.o: ../../src/common/object.cpp $(CXX) -c -o $@ $(BASELIB_CXXFLAGS) $(CPPDEPS) $< diff --git a/build/msw/makefile.vc b/build/msw/makefile.vc index c9b78c7298..322a1bfe3b 100644 --- a/build/msw/makefile.vc +++ b/build/msw/makefile.vc @@ -373,6 +373,7 @@ MONODLL_OBJECTS = \ $(OBJS)\monodll_mimecmn.obj \ $(OBJS)\monodll_module.obj \ $(OBJS)\monodll_mstream.obj \ + $(OBJS)\monodll_numformatter.obj \ $(OBJS)\monodll_object.obj \ $(OBJS)\monodll_platinfo.obj \ $(OBJS)\monodll_powercmn.obj \ @@ -527,6 +528,7 @@ MONOLIB_OBJECTS = \ $(OBJS)\monolib_mimecmn.obj \ $(OBJS)\monolib_module.obj \ $(OBJS)\monolib_mstream.obj \ + $(OBJS)\monolib_numformatter.obj \ $(OBJS)\monolib_object.obj \ $(OBJS)\monolib_platinfo.obj \ $(OBJS)\monolib_powercmn.obj \ @@ -677,6 +679,7 @@ BASEDLL_OBJECTS = \ $(OBJS)\basedll_mimecmn.obj \ $(OBJS)\basedll_module.obj \ $(OBJS)\basedll_mstream.obj \ + $(OBJS)\basedll_numformatter.obj \ $(OBJS)\basedll_object.obj \ $(OBJS)\basedll_platinfo.obj \ $(OBJS)\basedll_powercmn.obj \ @@ -813,6 +816,7 @@ BASELIB_OBJECTS = \ $(OBJS)\baselib_mimecmn.obj \ $(OBJS)\baselib_module.obj \ $(OBJS)\baselib_mstream.obj \ + $(OBJS)\baselib_numformatter.obj \ $(OBJS)\baselib_object.obj \ $(OBJS)\baselib_platinfo.obj \ $(OBJS)\baselib_powercmn.obj \ @@ -6580,6 +6584,9 @@ $(OBJS)\monodll_module.obj: ..\..\src\common\module.cpp $(OBJS)\monodll_mstream.obj: ..\..\src\common\mstream.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\common\mstream.cpp +$(OBJS)\monodll_numformatter.obj: ..\..\src\common\numformatter.cpp + $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\common\numformatter.cpp + $(OBJS)\monodll_object.obj: ..\..\src\common\object.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\common\object.cpp @@ -8902,6 +8909,9 @@ $(OBJS)\monolib_module.obj: ..\..\src\common\module.cpp $(OBJS)\monolib_mstream.obj: ..\..\src\common\mstream.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\common\mstream.cpp +$(OBJS)\monolib_numformatter.obj: ..\..\src\common\numformatter.cpp + $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\common\numformatter.cpp + $(OBJS)\monolib_object.obj: ..\..\src\common\object.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\common\object.cpp @@ -11224,6 +11234,9 @@ $(OBJS)\basedll_module.obj: ..\..\src\common\module.cpp $(OBJS)\basedll_mstream.obj: ..\..\src\common\mstream.cpp $(CXX) /c /nologo /TP /Fo$@ $(BASEDLL_CXXFLAGS) ..\..\src\common\mstream.cpp +$(OBJS)\basedll_numformatter.obj: ..\..\src\common\numformatter.cpp + $(CXX) /c /nologo /TP /Fo$@ $(BASEDLL_CXXFLAGS) ..\..\src\common\numformatter.cpp + $(OBJS)\basedll_object.obj: ..\..\src\common\object.cpp $(CXX) /c /nologo /TP /Fo$@ $(BASEDLL_CXXFLAGS) ..\..\src\common\object.cpp @@ -11557,6 +11570,9 @@ $(OBJS)\baselib_module.obj: ..\..\src\common\module.cpp $(OBJS)\baselib_mstream.obj: ..\..\src\common\mstream.cpp $(CXX) /c /nologo /TP /Fo$@ $(BASELIB_CXXFLAGS) ..\..\src\common\mstream.cpp +$(OBJS)\baselib_numformatter.obj: ..\..\src\common\numformatter.cpp + $(CXX) /c /nologo /TP /Fo$@ $(BASELIB_CXXFLAGS) ..\..\src\common\numformatter.cpp + $(OBJS)\baselib_object.obj: ..\..\src\common\object.cpp $(CXX) /c /nologo /TP /Fo$@ $(BASELIB_CXXFLAGS) ..\..\src\common\object.cpp diff --git a/build/msw/makefile.wat b/build/msw/makefile.wat index e90fcfeb58..86cd7fdcf9 100644 --- a/build/msw/makefile.wat +++ b/build/msw/makefile.wat @@ -3755,6 +3755,7 @@ MONODLL_OBJECTS = & $(OBJS)\monodll_mimecmn.obj & $(OBJS)\monodll_module.obj & $(OBJS)\monodll_mstream.obj & + $(OBJS)\monodll_numformatter.obj & $(OBJS)\monodll_object.obj & $(OBJS)\monodll_platinfo.obj & $(OBJS)\monodll_powercmn.obj & @@ -3901,6 +3902,7 @@ MONOLIB_OBJECTS = & $(OBJS)\monolib_mimecmn.obj & $(OBJS)\monolib_module.obj & $(OBJS)\monolib_mstream.obj & + $(OBJS)\monolib_numformatter.obj & $(OBJS)\monolib_object.obj & $(OBJS)\monolib_platinfo.obj & $(OBJS)\monolib_powercmn.obj & @@ -4045,6 +4047,7 @@ BASEDLL_OBJECTS = & $(OBJS)\basedll_mimecmn.obj & $(OBJS)\basedll_module.obj & $(OBJS)\basedll_mstream.obj & + $(OBJS)\basedll_numformatter.obj & $(OBJS)\basedll_object.obj & $(OBJS)\basedll_platinfo.obj & $(OBJS)\basedll_powercmn.obj & @@ -4174,6 +4177,7 @@ BASELIB_OBJECTS = & $(OBJS)\baselib_mimecmn.obj & $(OBJS)\baselib_module.obj & $(OBJS)\baselib_mstream.obj & + $(OBJS)\baselib_numformatter.obj & $(OBJS)\baselib_object.obj & $(OBJS)\baselib_platinfo.obj & $(OBJS)\baselib_powercmn.obj & @@ -6409,6 +6413,9 @@ $(OBJS)\monodll_module.obj : .AUTODEPEND ..\..\src\common\module.cpp $(OBJS)\monodll_mstream.obj : .AUTODEPEND ..\..\src\common\mstream.cpp $(CXX) -bt=nt -zq -fo=$^@ $(MONODLL_CXXFLAGS) $< +$(OBJS)\monodll_numformatter.obj : .AUTODEPEND ..\..\src\common\numformatter.cpp + $(CXX) -bt=nt -zq -fo=$^@ $(MONODLL_CXXFLAGS) $< + $(OBJS)\monodll_object.obj : .AUTODEPEND ..\..\src\common\object.cpp $(CXX) -bt=nt -zq -fo=$^@ $(MONODLL_CXXFLAGS) $< @@ -8731,6 +8738,9 @@ $(OBJS)\monolib_module.obj : .AUTODEPEND ..\..\src\common\module.cpp $(OBJS)\monolib_mstream.obj : .AUTODEPEND ..\..\src\common\mstream.cpp $(CXX) -bt=nt -zq -fo=$^@ $(MONOLIB_CXXFLAGS) $< +$(OBJS)\monolib_numformatter.obj : .AUTODEPEND ..\..\src\common\numformatter.cpp + $(CXX) -bt=nt -zq -fo=$^@ $(MONOLIB_CXXFLAGS) $< + $(OBJS)\monolib_object.obj : .AUTODEPEND ..\..\src\common\object.cpp $(CXX) -bt=nt -zq -fo=$^@ $(MONOLIB_CXXFLAGS) $< @@ -11053,6 +11063,9 @@ $(OBJS)\basedll_module.obj : .AUTODEPEND ..\..\src\common\module.cpp $(OBJS)\basedll_mstream.obj : .AUTODEPEND ..\..\src\common\mstream.cpp $(CXX) -bt=nt -zq -fo=$^@ $(BASEDLL_CXXFLAGS) $< +$(OBJS)\basedll_numformatter.obj : .AUTODEPEND ..\..\src\common\numformatter.cpp + $(CXX) -bt=nt -zq -fo=$^@ $(BASEDLL_CXXFLAGS) $< + $(OBJS)\basedll_object.obj : .AUTODEPEND ..\..\src\common\object.cpp $(CXX) -bt=nt -zq -fo=$^@ $(BASEDLL_CXXFLAGS) $< @@ -11386,6 +11399,9 @@ $(OBJS)\baselib_module.obj : .AUTODEPEND ..\..\src\common\module.cpp $(OBJS)\baselib_mstream.obj : .AUTODEPEND ..\..\src\common\mstream.cpp $(CXX) -bt=nt -zq -fo=$^@ $(BASELIB_CXXFLAGS) $< +$(OBJS)\baselib_numformatter.obj : .AUTODEPEND ..\..\src\common\numformatter.cpp + $(CXX) -bt=nt -zq -fo=$^@ $(BASELIB_CXXFLAGS) $< + $(OBJS)\baselib_object.obj : .AUTODEPEND ..\..\src\common\object.cpp $(CXX) -bt=nt -zq -fo=$^@ $(BASELIB_CXXFLAGS) $< diff --git a/build/msw/wx_base.dsp b/build/msw/wx_base.dsp index 0729616750..833d914cd9 100644 --- a/build/msw/wx_base.dsp +++ b/build/msw/wx_base.dsp @@ -451,6 +451,10 @@ SOURCE=..\..\src\common\mstream.cpp # End Source File # Begin Source File +SOURCE=..\..\src\common\numformatter.cpp +# End Source File +# Begin Source File + SOURCE=..\..\src\common\object.cpp # End Source File # Begin Source File @@ -1415,6 +1419,10 @@ SOURCE=..\..\include\wx\mstream.h # End Source File # Begin Source File +SOURCE=..\..\include\wx\numformatter.h +# End Source File +# Begin Source File + SOURCE=..\..\include\wx\object.h # End Source File # Begin Source File @@ -1659,6 +1667,10 @@ SOURCE=..\..\include\wx\xti.h # End Source File # Begin Source File +SOURCE=..\..\include\wx\xti2.h +# End Source File +# Begin Source File + SOURCE=..\..\include\wx\xtictor.h # End Source File # Begin Source File diff --git a/build/msw/wx_core.dsp b/build/msw/wx_core.dsp index e784b748ea..233278896e 100644 --- a/build/msw/wx_core.dsp +++ b/build/msw/wx_core.dsp @@ -6561,6 +6561,10 @@ SOURCE=..\..\include\wx\radiobut.h # End Source File # Begin Source File +SOURCE=..\..\include\wx\range.h +# End Source File +# Begin Source File + SOURCE=..\..\include\wx\rawbmp.h # End Source File # Begin Source File diff --git a/build/msw/wx_vc7_base.vcproj b/build/msw/wx_vc7_base.vcproj index dc7b035939..e1d56dfc69 100644 --- a/build/msw/wx_vc7_base.vcproj +++ b/build/msw/wx_vc7_base.vcproj @@ -778,6 +778,9 @@ RelativePath="..\..\src\common\mstream.cpp"> + + + + + + + + + + @@ -2010,6 +2014,10 @@ > + + @@ -2254,6 +2262,10 @@ > + + diff --git a/build/msw/wx_vc8_core.vcproj b/build/msw/wx_vc8_core.vcproj index 5a922dcc46..c84aa41ddc 100644 --- a/build/msw/wx_vc8_core.vcproj +++ b/build/msw/wx_vc8_core.vcproj @@ -7372,6 +7372,10 @@ > + + diff --git a/build/msw/wx_vc9_base.vcproj b/build/msw/wx_vc9_base.vcproj index 6529869148..a888a27815 100644 --- a/build/msw/wx_vc9_base.vcproj +++ b/build/msw/wx_vc9_base.vcproj @@ -1067,6 +1067,10 @@ > + + @@ -2006,6 +2010,10 @@ > + + @@ -2250,6 +2258,10 @@ > + + diff --git a/build/msw/wx_vc9_core.vcproj b/build/msw/wx_vc9_core.vcproj index af4b06be9a..d007bd54f5 100644 --- a/build/msw/wx_vc9_core.vcproj +++ b/build/msw/wx_vc9_core.vcproj @@ -7368,6 +7368,10 @@ > + + diff --git a/docs/changes.txt b/docs/changes.txt index 3f35549ed6..b1efe24315 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -422,6 +422,7 @@ All: - Added wxFile::GetLastError() and ClearLastError() (ryazanov). - Added negatable command line switches (Armel Asselin). - Added wxVersionInfo and various GetLibraryVersionInfo() functions (troelsk). +- Added wxNumberFormatter for dealing with thousands separators. Unix: diff --git a/include/wx/numformatter.h b/include/wx/numformatter.h new file mode 100644 index 0000000000..02bae6d531 --- /dev/null +++ b/include/wx/numformatter.h @@ -0,0 +1,69 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: wx/numformatter.h +// Purpose: wxNumberFormatter class +// Author: Fulvio Senore, Vadim Zeitlin +// Created: 2010-11-06 +// Copyright: (c) 2010 wxWidgets team +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_NUMFORMATTER_H_ +#define _WX_NUMFORMATTER_H_ + +#include "wx/string.h" + +// Helper class for formatting numbers with thousands separators which also +// supports parsing the numbers formatted by it. +class WXDLLIMPEXP_BASE wxNumberFormatter +{ +public: + // Bit masks for ToString() + enum Style + { + Style_None = 0x00, + Style_WithThousandsSep = 0x01, + Style_NoTrailingZeroes = 0x02 // Only for floating point numbers + }; + + // Format a number as a string. By default, the thousands separator is + // used, specify Style_None to prevent this. For floating point numbers, + // precision can also be specified. + static wxString ToString(long val, + int style = Style_WithThousandsSep); + + static wxString ToString(double val, + int precision, + int style = Style_WithThousandsSep); + + // Parse a string representing a number, possibly with thousands separator. + // + // Return true on success and stores the result in the provided location + // which must be a valid non-NULL pointer. + static bool FromString(wxString s, long *val); + static bool FromString(wxString s, double *val); + + + // Get the decimal separator for the current locale. It is always defined + // and we fall back to returning '.' in case of an error. + static wxChar GetDecimalSeparator(); + + // Get the thousands separator if grouping of the digits is used by the + // current locale. The value returned in sep should be only used if the + // function returns true. + static bool GetThousandsSeparatorIfUsed(wxChar *sep); + +private: + // Add the thousands separators to a string representing a number without + // the separators. This is used by ToString(Style_WithThousandsSep). + static void AddThousandsSeparators(wxString& s); + + // Remove trailing zeroes and, if there is nothing left after it, the + // decimal separator itself from a string representing a floating point + // number. Also used by ToString(). + static void RemoveTrailingZeroes(wxString& s); + + // Remove all thousands separators from a string representing a number. + static void RemoveThousandsSeparators(wxString& s); +}; + +#endif // _WX_NUMFORMATTER_H_ diff --git a/interface/wx/numformatter.h b/interface/wx/numformatter.h new file mode 100644 index 0000000000..e989692996 --- /dev/null +++ b/interface/wx/numformatter.h @@ -0,0 +1,126 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: wx/numformatter.h +// Purpose: interface to wxNumberFormatter +// Author: Fulvio Senore, Vadim Zeitlin +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +/** + @class wxNumberFormatter + + Helper class for formatting and parsing numbers with thousands separators. + + This class contains only static functions, so users must not create instances + but directly call the member functions. + + @since 2.9.2 + + @library{wxbase} +*/ +class wxNumberFormatter +{ +public: + /** + Bit masks used with ToString(). + */ + enum Style + { + /** + This flag cab be used to indicate absence of any other flags below. + */ + Style_None = 0x00, + + /** + If this flag is given, thousands separators will be inserted in the + number string representation as defined by the current locale. + */ + Style_WithThousandsSep = 0x01, + + /** + If this flag is given, trailing zeroes in a floating point number + string representation will be omitted. + + If the number is actually integer, the decimal separator will be + omitted as well. To give an example, formatting the number @c 1.23 + with precision 5 will normally yield "1.23000" but with this flag + it would return "1.23". And formatting @c 123 with this flag will + return just "123" for any precision. + + This flag can't be used with ToString() overload taking the integer + value. + */ + Style_NoTrailingZeroes = 0x02 + }; + + /** + 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 + flags in which case the call to the function has exactly the same + effect as wxString::Format("%ld", val). + + Notice that calling ToString() with a value of type @c int and + non-default flags results in ambiguity between this overload and the + one below. To resolve it, you need to cast the value to @c long. + + @param val + The variable to convert to a string. + @param flags + Combination of values from the Style enumeration (except for + Style_NoTrailingZeroes which can't be used with this overload). + */ + static wxString ToString(long val, int flags = Style_WithThousandsSep); + + /** + Returns string representation of a floating point number. + + @param val + The variable to convert to a string. + @param precision + Number of decimals to write in formatted string. + @param flags + Combination of values from the Style enumeration. + */ + static wxString + ToString(double val, int precision, int flags = Style_WithThousandsSep); + + + /** + Parse a string representation of a number possibly including thousands + separators. + + These functions parse number representation in the current 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. + + @see wxString::ToLong(), wxString::ToDouble() + */ + //@{ + static bool FromString(wxString s, long *val); + static bool FromString(wxString s, double *val); + //@} + + /** + Get the decimal separator for the current locale. + + Decimal separators is always defined and we fall back to returning '.' + in case of an error. + */ + static wxChar GetDecimalSeparator(); + + /** + Get the thousands separator if grouping of the digits is used by the + current 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 + function return value is needed. + */ + static bool GetThousandsSeparatorIfUsed(wxChar *sep); + +}; diff --git a/interface/wx/string.h b/interface/wx/string.h index 98ed23b861..f6ca6cd0f5 100644 --- a/interface/wx/string.h +++ b/interface/wx/string.h @@ -975,8 +975,13 @@ public: you are sure that this string contains a floating point number formatted with the rules of the locale currently in use (see wxLocale). - Refer to the docs of the standard function @c strtod() for more details about - the supported syntax. + Also notice that even this function is locale-specific it does not + support strings with thousands separators in them, even if the current + locale uses digits grouping. You may use wxNumberFormatter::FromString() + to parse such strings. + + Please refer to the documentation of the standard function @c strtod() + for more details about the supported syntax. @see ToCDouble(), ToLong(), ToULong() */ @@ -1015,8 +1020,12 @@ public: that this string contains an integer number formatted with the rules of the locale currently in use (see wxLocale). - Refer to the docs of the standard function @c strtol() for more details about - the supported syntax. + As with ToDouble(), this function does not support strings containing + thousands separators even if the current locale uses digits grouping. + You may use wxNumberFormatter::FromString() to parse such strings. + + Please refer to the documentation of the standard function @c strtol() + for more details about the supported syntax. @see ToCDouble(), ToDouble(), ToULong() */ diff --git a/src/common/numformatter.cpp b/src/common/numformatter.cpp new file mode 100644 index 0000000000..851259cbfd --- /dev/null +++ b/src/common/numformatter.cpp @@ -0,0 +1,190 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: numformatter.cpp +// Purpose: wxNumberFormatter +// Author: Fulvio Senore, Vadim Zeitlin +// Created: 2010-11-06 +// Copyright: (c) 2010 wxWidgets team +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#include "wx/numformatter.h" +#include "wx/intl.h" + +// ============================================================================ +// wxNumberFormatter implementation +// ============================================================================ + +// ---------------------------------------------------------------------------- +// Locale information accessors +// ---------------------------------------------------------------------------- + +wxChar wxNumberFormatter::GetDecimalSeparator() +{ + // Notice that while using static variable here is not MT-safe, the worst + // that can happen is that we redo the initialization if we're called + // concurrently from more than one thread so it's not a real problem. + static wxChar s_decimalSeparator = 0; + + if ( !s_decimalSeparator ) + { + const wxString + s = wxLocale::GetInfo(wxLOCALE_DECIMAL_POINT, wxLOCALE_CAT_NUMBER); + if ( s.empty() ) + { + // We really must have something for decimal separator, so fall + // back to the C locale default. + s_decimalSeparator = '.'; + } + else + { + // To the best of my knowledge there are no locales like this. + wxASSERT_MSG( s.length() == 1, + "Multi-character decimal separator?" ); + + s_decimalSeparator = s[0]; + } + } + + return s_decimalSeparator; +} + +bool wxNumberFormatter::GetThousandsSeparatorIfUsed(wxChar *sep) +{ + static wxChar s_thousandsSeparator = 0; + static bool s_initialized = false; + + if ( !s_initialized ) + { + const wxString + s = wxLocale::GetInfo(wxLOCALE_THOUSANDS_SEP, wxLOCALE_CAT_NUMBER); + if ( !s.empty() ) + { + wxASSERT_MSG( s.length() == 1, + "Multi-character thousands separator?" ); + + s_thousandsSeparator = s[0]; + } + //else: Unlike above it's perfectly fine for the thousands separator to + // be empty if grouping is not used, so just leave it as 0. + + s_initialized = true; + } + + if ( !s_thousandsSeparator ) + return false; + + if ( sep ) + *sep = s_thousandsSeparator; + + return true; +} + +// ---------------------------------------------------------------------------- +// Conversion to string and helpers +// ---------------------------------------------------------------------------- + +wxString wxNumberFormatter::ToString(long val, int style) +{ + wxString s = wxString::Format("%ld", val); + + if ( style & Style_WithThousandsSep ) + AddThousandsSeparators(s); + + wxASSERT_MSG( !(style & Style_NoTrailingZeroes), + "Style_NoTrailingZeroes can't be used with integer values" ); + + return s; +} + +wxString wxNumberFormatter::ToString(double val, int precision, int style) +{ + const wxString fmt = wxString::Format("%%.%df", precision); + wxString s = wxString::Format(fmt, val); + + if ( style & Style_WithThousandsSep ) + AddThousandsSeparators(s); + + if ( style & Style_NoTrailingZeroes ) + RemoveTrailingZeroes(s); + + return s; +} + +void wxNumberFormatter::AddThousandsSeparators(wxString& s) +{ + wxChar thousandsSep; + if ( !GetThousandsSeparatorIfUsed(&thousandsSep) ) + return; + + size_t pos = s.find(GetDecimalSeparator()); + if ( pos == wxString::npos ) + { + // Start grouping at the end of an integer number. + pos = s.length(); + } + + // We currently group digits by 3 independently of the locale. This is not + // the right thing to do and we should use lconv::grouping (under POSIX) + // and GetLocaleInfo(LOCALE_SGROUPING) (under MSW) to get information about + // the correct grouping to use. This is something that needs to be done at + // wxLocale level first and then used here in the future (TODO). + const size_t GROUP_LEN = 3; + + while ( pos > GROUP_LEN ) + { + pos -= GROUP_LEN; + s.insert(pos, thousandsSep); + } +} + +void wxNumberFormatter::RemoveTrailingZeroes(wxString& s) +{ + const size_t posDecSep = s.find(GetDecimalSeparator()); + wxCHECK_RET( posDecSep != wxString::npos, "No decimal separator" ); + wxCHECK_RET( posDecSep, "Can't start with decimal separator" ); + + // Find the last character to keep. + size_t posLastNonZero = s.find_last_not_of("0"); + + // If it's the decimal separator itself, don't keep it neither. + if ( posLastNonZero == posDecSep ) + posLastNonZero--; + + s.erase(posLastNonZero + 1); +} + +// ---------------------------------------------------------------------------- +// Conversion from strings +// ---------------------------------------------------------------------------- + +void wxNumberFormatter::RemoveThousandsSeparators(wxString& s) +{ + wxChar thousandsSep; + if ( !GetThousandsSeparatorIfUsed(&thousandsSep) ) + return; + + s.Replace(wxString(thousandsSep), wxString()); +} + +bool wxNumberFormatter::FromString(wxString s, long *val) +{ + RemoveThousandsSeparators(s); + return s.ToLong(val); +} + +bool wxNumberFormatter::FromString(wxString s, double *val) +{ + RemoveThousandsSeparators(s); + return s.ToDouble(val); +} diff --git a/tests/Makefile.in b/tests/Makefile.in index 995b5c84b3..53b6e4dcc1 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -100,6 +100,7 @@ TEST_OBJECTS = \ test_wxregextest.o \ test_scopeguardtest.o \ test_iostream.o \ + test_numformatter.o \ test_strings.o \ test_stdstrings.o \ test_tokenizer.o \ @@ -550,6 +551,9 @@ test_scopeguardtest.o: $(srcdir)/scopeguard/scopeguardtest.cpp $(TEST_ODEP) test_iostream.o: $(srcdir)/strings/iostream.cpp $(TEST_ODEP) $(CXXC) -c -o $@ $(TEST_CXXFLAGS) $(srcdir)/strings/iostream.cpp +test_numformatter.o: $(srcdir)/strings/numformatter.cpp $(TEST_ODEP) + $(CXXC) -c -o $@ $(TEST_CXXFLAGS) $(srcdir)/strings/numformatter.cpp + test_strings.o: $(srcdir)/strings/strings.cpp $(TEST_ODEP) $(CXXC) -c -o $@ $(TEST_CXXFLAGS) $(srcdir)/strings/strings.cpp diff --git a/tests/makefile.bcc b/tests/makefile.bcc index dea2043537..53a429011f 100644 --- a/tests/makefile.bcc +++ b/tests/makefile.bcc @@ -84,6 +84,7 @@ TEST_OBJECTS = \ $(OBJS)\test_wxregextest.obj \ $(OBJS)\test_scopeguardtest.obj \ $(OBJS)\test_iostream.obj \ + $(OBJS)\test_numformatter.obj \ $(OBJS)\test_strings.obj \ $(OBJS)\test_stdstrings.obj \ $(OBJS)\test_tokenizer.obj \ @@ -593,6 +594,9 @@ $(OBJS)\test_scopeguardtest.obj: .\scopeguard\scopeguardtest.cpp $(OBJS)\test_iostream.obj: .\strings\iostream.cpp $(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) .\strings\iostream.cpp +$(OBJS)\test_numformatter.obj: .\strings\numformatter.cpp + $(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) .\strings\numformatter.cpp + $(OBJS)\test_strings.obj: .\strings\strings.cpp $(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) .\strings\strings.cpp diff --git a/tests/makefile.gcc b/tests/makefile.gcc index 9c4aa0e01b..505525af14 100644 --- a/tests/makefile.gcc +++ b/tests/makefile.gcc @@ -76,6 +76,7 @@ TEST_OBJECTS = \ $(OBJS)\test_wxregextest.o \ $(OBJS)\test_scopeguardtest.o \ $(OBJS)\test_iostream.o \ + $(OBJS)\test_numformatter.o \ $(OBJS)\test_strings.o \ $(OBJS)\test_stdstrings.o \ $(OBJS)\test_tokenizer.o \ @@ -574,6 +575,9 @@ $(OBJS)\test_scopeguardtest.o: ./scopeguard/scopeguardtest.cpp $(OBJS)\test_iostream.o: ./strings/iostream.cpp $(CXX) -c -o $@ $(TEST_CXXFLAGS) $(CPPDEPS) $< +$(OBJS)\test_numformatter.o: ./strings/numformatter.cpp + $(CXX) -c -o $@ $(TEST_CXXFLAGS) $(CPPDEPS) $< + $(OBJS)\test_strings.o: ./strings/strings.cpp $(CXX) -c -o $@ $(TEST_CXXFLAGS) $(CPPDEPS) $< diff --git a/tests/makefile.vc b/tests/makefile.vc index 88280b900a..233b854b2f 100644 --- a/tests/makefile.vc +++ b/tests/makefile.vc @@ -78,6 +78,7 @@ TEST_OBJECTS = \ $(OBJS)\test_wxregextest.obj \ $(OBJS)\test_scopeguardtest.obj \ $(OBJS)\test_iostream.obj \ + $(OBJS)\test_numformatter.obj \ $(OBJS)\test_strings.obj \ $(OBJS)\test_stdstrings.obj \ $(OBJS)\test_tokenizer.obj \ @@ -719,6 +720,9 @@ $(OBJS)\test_scopeguardtest.obj: .\scopeguard\scopeguardtest.cpp $(OBJS)\test_iostream.obj: .\strings\iostream.cpp $(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) .\strings\iostream.cpp +$(OBJS)\test_numformatter.obj: .\strings\numformatter.cpp + $(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) .\strings\numformatter.cpp + $(OBJS)\test_strings.obj: .\strings\strings.cpp $(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) .\strings\strings.cpp diff --git a/tests/makefile.wat b/tests/makefile.wat index 90dff37c9a..e35199ad19 100644 --- a/tests/makefile.wat +++ b/tests/makefile.wat @@ -319,6 +319,7 @@ TEST_OBJECTS = & $(OBJS)\test_wxregextest.obj & $(OBJS)\test_scopeguardtest.obj & $(OBJS)\test_iostream.obj & + $(OBJS)\test_numformatter.obj & $(OBJS)\test_strings.obj & $(OBJS)\test_stdstrings.obj & $(OBJS)\test_tokenizer.obj & @@ -632,6 +633,9 @@ $(OBJS)\test_scopeguardtest.obj : .AUTODEPEND .\scopeguard\scopeguardtest.cpp $(OBJS)\test_iostream.obj : .AUTODEPEND .\strings\iostream.cpp $(CXX) -bt=nt -zq -fo=$^@ $(TEST_CXXFLAGS) $< +$(OBJS)\test_numformatter.obj : .AUTODEPEND .\strings\numformatter.cpp + $(CXX) -bt=nt -zq -fo=$^@ $(TEST_CXXFLAGS) $< + $(OBJS)\test_strings.obj : .AUTODEPEND .\strings\strings.cpp $(CXX) -bt=nt -zq -fo=$^@ $(TEST_CXXFLAGS) $< diff --git a/tests/strings/numformatter.cpp b/tests/strings/numformatter.cpp new file mode 100644 index 0000000000..30784dd120 --- /dev/null +++ b/tests/strings/numformatter.cpp @@ -0,0 +1,239 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: tests/strings/numformat.cpp +// Purpose: wxNumberFormatter unit test +// Author: Vadim Zeitlin +// Created: 2011-01-15 +// RCS-ID: $Id$ +// Copyright: (c) 2011 Vadim Zeitlin +/////////////////////////////////////////////////////////////////////////////// + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +#include "testprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#include "wx/numformatter.h" +#include "wx/intl.h" + +// ---------------------------------------------------------------------------- +// test class +// ---------------------------------------------------------------------------- + +class NumFormatterTestCase : public CppUnit::TestCase +{ +public: + NumFormatterTestCase() + { + // We need to use a locale with known decimal point and which uses the + // thousands separator for the tests to make sense. + wxLanguage lang; + if ( wxLocale::IsAvailable(wxLANGUAGE_ENGLISH_US) ) + lang = wxLANGUAGE_ENGLISH_US; + else if ( wxLocale::IsAvailable(wxLANGUAGE_ENGLISH_UK) ) + lang = wxLANGUAGE_ENGLISH_UK; + else + { + m_locale = NULL; + return; + } + + m_locale = new wxLocale(lang, wxLOCALE_DONT_LOAD_DEFAULT); + } + + virtual ~NumFormatterTestCase() + { + delete m_locale; + } + +private: + CPPUNIT_TEST_SUITE( NumFormatterTestCase ); + CPPUNIT_TEST( LongToString ); + CPPUNIT_TEST( DoubleToString ); + CPPUNIT_TEST( NoTrailingZeroes ); + CPPUNIT_TEST( LongFromString ); + CPPUNIT_TEST( DoubleFromString ); + CPPUNIT_TEST_SUITE_END(); + + void LongToString(); + void DoubleToString(); + void NoTrailingZeroes(); + void LongFromString(); + void DoubleFromString(); + + wxLocale *m_locale; + + wxDECLARE_NO_COPY_CLASS(NumFormatterTestCase); +}; + +// register in the unnamed registry so that these tests are run by default +CPPUNIT_TEST_SUITE_REGISTRATION( NumFormatterTestCase ); + +// also include in it's own registry so that these tests can be run alone +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( NumFormatterTestCase, "NumFormatterTestCase" ); + +// ---------------------------------------------------------------------------- +// tests themselves +// ---------------------------------------------------------------------------- + +void NumFormatterTestCase::LongToString() +{ + if ( !m_locale ) + return; + + CPPUNIT_ASSERT_EQUAL( "1", wxNumberFormatter::ToString( 1)); + CPPUNIT_ASSERT_EQUAL( "12", wxNumberFormatter::ToString( 12)); + CPPUNIT_ASSERT_EQUAL( "123", wxNumberFormatter::ToString( 123)); + CPPUNIT_ASSERT_EQUAL( "1,234", wxNumberFormatter::ToString( 1234)); + CPPUNIT_ASSERT_EQUAL( "12,345", wxNumberFormatter::ToString( 12345)); + CPPUNIT_ASSERT_EQUAL( "123,456", wxNumberFormatter::ToString( 123456)); + CPPUNIT_ASSERT_EQUAL( "1,234,567", wxNumberFormatter::ToString( 1234567)); + CPPUNIT_ASSERT_EQUAL( "12,345,678", wxNumberFormatter::ToString( 12345678)); + CPPUNIT_ASSERT_EQUAL("123,456,789", wxNumberFormatter::ToString( 123456789)); +} + +void NumFormatterTestCase::DoubleToString() +{ + if ( !m_locale ) + return; + + CPPUNIT_ASSERT_EQUAL("1.0", wxNumberFormatter::ToString(1., 1)); + CPPUNIT_ASSERT_EQUAL("0.123456", wxNumberFormatter::ToString(0.123456, 6)); + CPPUNIT_ASSERT_EQUAL("1.234567", wxNumberFormatter::ToString(1.234567, 6)); + CPPUNIT_ASSERT_EQUAL("12.34567", wxNumberFormatter::ToString(12.34567, 5)); + CPPUNIT_ASSERT_EQUAL("123.4567", wxNumberFormatter::ToString(123.4567, 4)); + CPPUNIT_ASSERT_EQUAL("1,234.56", wxNumberFormatter::ToString(1234.56, 2)); + CPPUNIT_ASSERT_EQUAL("12,345.6", wxNumberFormatter::ToString(12345.6, 1)); + CPPUNIT_ASSERT_EQUAL("12,345.6", wxNumberFormatter::ToString(12345.6, 1)); + CPPUNIT_ASSERT_EQUAL("123,456,789.0", + wxNumberFormatter::ToString(123456789., 1)); + CPPUNIT_ASSERT_EQUAL("123,456,789.012", + wxNumberFormatter::ToString(123456789.012, 3)); +} + +void NumFormatterTestCase::NoTrailingZeroes() +{ + WX_ASSERT_FAILS_WITH_ASSERT + ( + wxNumberFormatter::ToString(123L, wxNumberFormatter::Style_NoTrailingZeroes) + ); + + if ( !m_locale ) + return; + + CPPUNIT_ASSERT_EQUAL + ( + "123.000", + wxNumberFormatter::ToString(123., 3) + ); + + CPPUNIT_ASSERT_EQUAL + ( + "123", + wxNumberFormatter::ToString(123., 3, wxNumberFormatter::Style_NoTrailingZeroes) + ); + + CPPUNIT_ASSERT_EQUAL + ( + "123", + wxNumberFormatter::ToString(123., 9, wxNumberFormatter::Style_NoTrailingZeroes) + ); + + CPPUNIT_ASSERT_EQUAL + ( + "123.456", + wxNumberFormatter::ToString(123.456, 3, wxNumberFormatter::Style_NoTrailingZeroes) + ); + + CPPUNIT_ASSERT_EQUAL + ( + "123.456000000", + wxNumberFormatter::ToString(123.456, 9) + ); + + CPPUNIT_ASSERT_EQUAL + ( + "123.456", + wxNumberFormatter::ToString(123.456, 9, wxNumberFormatter::Style_NoTrailingZeroes) + ); +} + +void NumFormatterTestCase::LongFromString() +{ + if ( !m_locale ) + return; + + WX_ASSERT_FAILS_WITH_ASSERT + ( + wxNumberFormatter::FromString("123", static_cast(0)) + ); + + long l; + CPPUNIT_ASSERT( !wxNumberFormatter::FromString("", &l) ); + CPPUNIT_ASSERT( !wxNumberFormatter::FromString("foo", &l) ); + CPPUNIT_ASSERT( !wxNumberFormatter::FromString("1.234", &l) ); + + CPPUNIT_ASSERT( wxNumberFormatter::FromString("123", &l) ); + CPPUNIT_ASSERT_EQUAL( 123, l ); + + CPPUNIT_ASSERT( wxNumberFormatter::FromString("1234", &l) ); + CPPUNIT_ASSERT_EQUAL( 1234, l ); + + CPPUNIT_ASSERT( wxNumberFormatter::FromString("1,234", &l) ); + CPPUNIT_ASSERT_EQUAL( 1234, l ); + + CPPUNIT_ASSERT( wxNumberFormatter::FromString("12,345", &l) ); + CPPUNIT_ASSERT_EQUAL( 12345, l ); + + CPPUNIT_ASSERT( wxNumberFormatter::FromString("123,456", &l) ); + CPPUNIT_ASSERT_EQUAL( 123456, l ); + + CPPUNIT_ASSERT( wxNumberFormatter::FromString("1,234,567", &l) ); + CPPUNIT_ASSERT_EQUAL( 1234567, l ); +} + +void NumFormatterTestCase::DoubleFromString() +{ + if ( !m_locale ) + return; + + WX_ASSERT_FAILS_WITH_ASSERT + ( + wxNumberFormatter::FromString("123", static_cast(0)) + ); + + double d; + CPPUNIT_ASSERT( !wxNumberFormatter::FromString("", &d) ); + CPPUNIT_ASSERT( !wxNumberFormatter::FromString("bar", &d) ); + + CPPUNIT_ASSERT( wxNumberFormatter::FromString("123", &d) ); + CPPUNIT_ASSERT_EQUAL( 123., d ); + + CPPUNIT_ASSERT( wxNumberFormatter::FromString("123.456789012", &d) ); + CPPUNIT_ASSERT_EQUAL( 123.456789012, d ); + + CPPUNIT_ASSERT( wxNumberFormatter::FromString("1,234.56789012", &d) ); + CPPUNIT_ASSERT_EQUAL( 1234.56789012, d ); + + CPPUNIT_ASSERT( wxNumberFormatter::FromString("12,345.6789012", &d) ); + CPPUNIT_ASSERT_EQUAL( 12345.6789012, d ); + + CPPUNIT_ASSERT( wxNumberFormatter::FromString("123,456.789012", &d) ); + CPPUNIT_ASSERT_EQUAL( 123456.789012, d ); + + CPPUNIT_ASSERT( wxNumberFormatter::FromString("1,234,567.89012", &d) ); + CPPUNIT_ASSERT_EQUAL( 1234567.89012, d ); + + CPPUNIT_ASSERT( wxNumberFormatter::FromString("12,345,678.9012", &d) ); + CPPUNIT_ASSERT_EQUAL( 12345678.9012, d ); + + CPPUNIT_ASSERT( wxNumberFormatter::FromString("123,456,789.012", &d) ); + CPPUNIT_ASSERT_EQUAL( 123456789.012, d ); + + CPPUNIT_ASSERT( wxNumberFormatter::FromString("123456789.012", &d) ); + CPPUNIT_ASSERT_EQUAL( 123456789.012, d ); +} diff --git a/tests/test.bkl b/tests/test.bkl index 9afe6d54d8..e11e136054 100644 --- a/tests/test.bkl +++ b/tests/test.bkl @@ -75,6 +75,7 @@ regex/wxregextest.cpp scopeguard/scopeguardtest.cpp strings/iostream.cpp + strings/numformatter.cpp strings/strings.cpp strings/stdstrings.cpp strings/tokenizer.cpp diff --git a/tests/test_test.dsp b/tests/test_test.dsp index 57d10245f1..96ee1ec6b1 100644 --- a/tests/test_test.dsp +++ b/tests/test_test.dsp @@ -429,6 +429,10 @@ SOURCE=.\misc\module.cpp # End Source File # Begin Source File +SOURCE=.\strings\numformatter.cpp +# End Source File +# Begin Source File + SOURCE=.\interactive\output.cpp # End Source File # Begin Source File diff --git a/tests/test_vc7_test.vcproj b/tests/test_vc7_test.vcproj index 753e3489ca..1c0e9d08a6 100644 --- a/tests/test_vc7_test.vcproj +++ b/tests/test_vc7_test.vcproj @@ -758,6 +758,9 @@ RelativePath=".\misc\module.cpp"> + + + + diff --git a/tests/test_vc9_test.vcproj b/tests/test_vc9_test.vcproj index c35f4cb7aa..58ec3cdcbe 100644 --- a/tests/test_vc9_test.vcproj +++ b/tests/test_vc9_test.vcproj @@ -1056,6 +1056,10 @@ > + + diff --git a/wxGTK.spec b/wxGTK.spec index e6f3076cc9..ae6e400837 100644 --- a/wxGTK.spec +++ b/wxGTK.spec @@ -270,6 +270,7 @@ wx/mousestate.h wx/msgout.h wx/msgqueue.h wx/mstream.h +wx/numformatter.h wx/object.h wx/platform.h wx/platinfo.h diff --git a/wxMotif.spec b/wxMotif.spec index d42149894c..54bf5c51a4 100644 --- a/wxMotif.spec +++ b/wxMotif.spec @@ -172,6 +172,7 @@ wx/mousestate.h wx/msgout.h wx/msgqueue.h wx/mstream.h +wx/numformatter.h wx/object.h wx/platform.h wx/platinfo.h diff --git a/wxX11.spec b/wxX11.spec index 36ad6ed3c3..cf642ac112 100644 --- a/wxX11.spec +++ b/wxX11.spec @@ -196,6 +196,7 @@ wx/mousestate.h wx/msgout.h wx/msgqueue.h wx/mstream.h +wx/numformatter.h wx/object.h wx/platform.h wx/platinfo.h -- 2.45.2