diff --git a/Makefile.in b/Makefile.in index 3ce1f73320..519cf77147 100644 --- a/Makefile.in +++ b/Makefile.in @@ -581,6 +581,8 @@ ALL_BASE_HEADERS = \ wx/generic/fswatcher.h \ wx/secretstore.h \ wx/lzmastream.h \ + wx/localedefs.h \ + wx/uilocale.h \ $(BASE_PLATFORM_HDR) \ wx/fs_inet.h \ wx/protocol/file.h \ @@ -766,6 +768,8 @@ ALL_PORTS_BASE_HEADERS = \ wx/generic/fswatcher.h \ wx/secretstore.h \ wx/lzmastream.h \ + wx/localedefs.h \ + wx/uilocale.h \ wx/unix/app.h \ wx/unix/apptbase.h \ wx/unix/apptrait.h \ @@ -905,6 +909,7 @@ ALL_BASE_SOURCES = \ src/generic/fswatcherg.cpp \ src/common/secretstore.cpp \ src/common/lzmastream.cpp \ + src/common/uilocale.cpp \ src/common/fdiodispatcher.cpp \ src/common/selectdispatcher.cpp \ src/unix/appunix.cpp \ @@ -924,6 +929,7 @@ ALL_BASE_SOURCES = \ src/unix/fswatcher_inotify.cpp \ src/unix/stdpaths.cpp \ src/unix/secretstore.cpp \ + src/unix/uilocale.cpp \ src/msw/basemsw.cpp \ src/msw/crashrpt.cpp \ src/msw/debughlp.cpp \ @@ -944,6 +950,7 @@ ALL_BASE_SOURCES = \ src/msw/utilsexc.cpp \ src/msw/fswatcher.cpp \ src/msw/secretstore.cpp \ + src/msw/uilocale.cpp \ $(BASE_OSX_SRC) \ src/common/event.cpp \ src/common/fs_mem.cpp \ @@ -1093,6 +1100,7 @@ MONODLL_OBJECTS = \ monodll_fswatcherg.o \ monodll_common_secretstore.o \ monodll_lzmastream.o \ + monodll_common_uilocale.o \ $(__BASE_PLATFORM_SRC_OBJECTS) \ monodll_event.o \ monodll_fs_mem.o \ @@ -1235,6 +1243,7 @@ MONOLIB_OBJECTS = \ monolib_fswatcherg.o \ monolib_common_secretstore.o \ monolib_lzmastream.o \ + monolib_common_uilocale.o \ $(__BASE_PLATFORM_SRC_OBJECTS_1) \ monolib_event.o \ monolib_fs_mem.o \ @@ -1365,6 +1374,7 @@ BASEDLL_OBJECTS = \ basedll_fswatcherg.o \ basedll_common_secretstore.o \ basedll_lzmastream.o \ + basedll_common_uilocale.o \ $(__BASE_PLATFORM_SRC_OBJECTS_2) \ basedll_event.o \ basedll_fs_mem.o \ @@ -1477,6 +1487,7 @@ BASELIB_OBJECTS = \ baselib_fswatcherg.o \ baselib_common_secretstore.o \ baselib_lzmastream.o \ + baselib_common_uilocale.o \ $(__BASE_PLATFORM_SRC_OBJECTS_3) \ baselib_event.o \ baselib_fs_mem.o \ @@ -2357,6 +2368,7 @@ COND_TOOLKIT_OSX_COCOA_BASE_OSX_SRC = \ src/osx/core/strconv_cf.cpp \ src/osx/cocoa/utils_base.mm \ src/osx/core/secretstore.cpp \ + src/osx/core/uilocale.cpp \ src/common/fdiodispatcher.cpp \ src/common/selectdispatcher.cpp \ src/unix/appunix.cpp \ @@ -2382,6 +2394,7 @@ COND_TOOLKIT_OSX_IPHONE_BASE_OSX_SRC = \ src/osx/core/strconv_cf.cpp \ src/osx/cocoa/utils_base.mm \ src/osx/core/secretstore.cpp \ + src/osx/core/uilocale.cpp \ src/common/fdiodispatcher.cpp \ src/common/selectdispatcher.cpp \ src/unix/appunix.cpp \ @@ -2421,7 +2434,8 @@ COND_TOOLKIT_COCOA_BASE_OSX_SRC = \ src/osx/core/evtloop_cf.cpp \ src/osx/core/strconv_cf.cpp \ src/osx/cocoa/utils_base.mm \ - src/osx/core/secretstore.cpp + src/osx/core/secretstore.cpp \ + src/osx/core/uilocale.cpp @COND_TOOLKIT_COCOA@BASE_OSX_SRC = $(COND_TOOLKIT_COCOA_BASE_OSX_SRC) COND_TOOLKIT_GTK_BASE_OSX_SRC = \ src/common/fdiodispatcher.cpp \ @@ -2444,7 +2458,8 @@ COND_TOOLKIT_GTK_BASE_OSX_SRC = \ src/osx/core/evtloop_cf.cpp \ src/osx/core/strconv_cf.cpp \ src/osx/cocoa/utils_base.mm \ - src/osx/core/secretstore.cpp + src/osx/core/secretstore.cpp \ + src/osx/core/uilocale.cpp @COND_TOOLKIT_GTK@BASE_OSX_SRC = $(COND_TOOLKIT_GTK_BASE_OSX_SRC) COND_TOOLKIT_X11_BASE_OSX_SRC = \ src/common/fdiodispatcher.cpp \ @@ -2467,7 +2482,8 @@ COND_TOOLKIT_X11_BASE_OSX_SRC = \ src/osx/core/evtloop_cf.cpp \ src/osx/core/strconv_cf.cpp \ src/osx/cocoa/utils_base.mm \ - src/osx/core/secretstore.cpp + src/osx/core/secretstore.cpp \ + src/osx/core/uilocale.cpp @COND_TOOLKIT_X11@BASE_OSX_SRC = $(COND_TOOLKIT_X11_BASE_OSX_SRC) COND_TOOLKIT_MOTIF_BASE_OSX_SRC = \ src/common/fdiodispatcher.cpp \ @@ -2490,7 +2506,8 @@ COND_TOOLKIT_MOTIF_BASE_OSX_SRC = \ src/osx/core/evtloop_cf.cpp \ src/osx/core/strconv_cf.cpp \ src/osx/cocoa/utils_base.mm \ - src/osx/core/secretstore.cpp + src/osx/core/secretstore.cpp \ + src/osx/core/uilocale.cpp @COND_TOOLKIT_MOTIF@BASE_OSX_SRC = $(COND_TOOLKIT_MOTIF_BASE_OSX_SRC) COND_TOOLKIT__BASE_OSX_SRC = \ src/common/fdiodispatcher.cpp \ @@ -2513,7 +2530,8 @@ COND_TOOLKIT__BASE_OSX_SRC = \ src/osx/core/evtloop_cf.cpp \ src/osx/core/strconv_cf.cpp \ src/osx/cocoa/utils_base.mm \ - src/osx/core/secretstore.cpp + src/osx/core/secretstore.cpp \ + src/osx/core/uilocale.cpp @COND_TOOLKIT_@BASE_OSX_SRC = $(COND_TOOLKIT__BASE_OSX_SRC) COND_TOOLKIT_OSX_COCOA_BASE_OSX_HDR = \ wx/osx/core/cfdataref.h \ @@ -4259,6 +4277,7 @@ COND_PLATFORM_MACOSX_1___BASE_PLATFORM_SRC_OBJECTS = \ monodll_strconv_cf.o \ monodll_utils_base.o \ monodll_core_secretstore.o \ + monodll_core_uilocale.o \ monodll_fdiodispatcher.o \ monodll_selectdispatcher.o \ monodll_appunix.o \ @@ -4296,7 +4315,8 @@ COND_PLATFORM_UNIX_1___BASE_PLATFORM_SRC_OBJECTS = \ monodll_unix_mimetype.o \ monodll_fswatcher_inotify.o \ monodll_unix_stdpaths.o \ - monodll_unix_secretstore.o + monodll_unix_secretstore.o \ + monodll_unix_uilocale.o @COND_PLATFORM_UNIX_1@__BASE_PLATFORM_SRC_OBJECTS = $(COND_PLATFORM_UNIX_1___BASE_PLATFORM_SRC_OBJECTS) COND_PLATFORM_WIN32_1___BASE_PLATFORM_SRC_OBJECTS = \ monodll_basemsw.o \ @@ -4318,7 +4338,8 @@ COND_PLATFORM_WIN32_1___BASE_PLATFORM_SRC_OBJECTS = \ monodll_msw_utils.o \ monodll_utilsexc.o \ monodll_fswatcher.o \ - monodll_msw_secretstore.o + monodll_msw_secretstore.o \ + monodll_msw_uilocale.o @COND_PLATFORM_WIN32_1@__BASE_PLATFORM_SRC_OBJECTS = $(COND_PLATFORM_WIN32_1___BASE_PLATFORM_SRC_OBJECTS) @COND_PLATFORM_WIN32_1@__BASE_AND_GUI_PLATFORM_SRC_OBJECTS \ @COND_PLATFORM_WIN32_1@ = monodll_msw_main.o monodll_volume.o @@ -6252,6 +6273,7 @@ COND_PLATFORM_MACOSX_1___BASE_PLATFORM_SRC_OBJECTS_1 = \ monolib_strconv_cf.o \ monolib_utils_base.o \ monolib_core_secretstore.o \ + monolib_core_uilocale.o \ monolib_fdiodispatcher.o \ monolib_selectdispatcher.o \ monolib_appunix.o \ @@ -6289,7 +6311,8 @@ COND_PLATFORM_UNIX_1___BASE_PLATFORM_SRC_OBJECTS_1 = \ monolib_unix_mimetype.o \ monolib_fswatcher_inotify.o \ monolib_unix_stdpaths.o \ - monolib_unix_secretstore.o + monolib_unix_secretstore.o \ + monolib_unix_uilocale.o @COND_PLATFORM_UNIX_1@__BASE_PLATFORM_SRC_OBJECTS_1 = $(COND_PLATFORM_UNIX_1___BASE_PLATFORM_SRC_OBJECTS_1) COND_PLATFORM_WIN32_1___BASE_PLATFORM_SRC_OBJECTS_1 = \ monolib_basemsw.o \ @@ -6311,7 +6334,8 @@ COND_PLATFORM_WIN32_1___BASE_PLATFORM_SRC_OBJECTS_1 = \ monolib_msw_utils.o \ monolib_utilsexc.o \ monolib_fswatcher.o \ - monolib_msw_secretstore.o + monolib_msw_secretstore.o \ + monolib_msw_uilocale.o @COND_PLATFORM_WIN32_1@__BASE_PLATFORM_SRC_OBJECTS_1 = $(COND_PLATFORM_WIN32_1___BASE_PLATFORM_SRC_OBJECTS_1) @COND_PLATFORM_WIN32_1@__BASE_AND_GUI_PLATFORM_SRC_OBJECTS_1 \ @COND_PLATFORM_WIN32_1@ = monolib_msw_main.o monolib_volume.o @@ -8297,6 +8321,7 @@ COND_PLATFORM_MACOSX_1___BASE_PLATFORM_SRC_OBJECTS_2 = \ basedll_strconv_cf.o \ basedll_utils_base.o \ basedll_core_secretstore.o \ + basedll_core_uilocale.o \ basedll_fdiodispatcher.o \ basedll_selectdispatcher.o \ basedll_appunix.o \ @@ -8334,7 +8359,8 @@ COND_PLATFORM_UNIX_1___BASE_PLATFORM_SRC_OBJECTS_2 = \ basedll_unix_mimetype.o \ basedll_fswatcher_inotify.o \ basedll_unix_stdpaths.o \ - basedll_unix_secretstore.o + basedll_unix_secretstore.o \ + basedll_unix_uilocale.o @COND_PLATFORM_UNIX_1@__BASE_PLATFORM_SRC_OBJECTS_2 = $(COND_PLATFORM_UNIX_1___BASE_PLATFORM_SRC_OBJECTS_2) COND_PLATFORM_WIN32_1___BASE_PLATFORM_SRC_OBJECTS_2 = \ basedll_basemsw.o \ @@ -8356,7 +8382,8 @@ COND_PLATFORM_WIN32_1___BASE_PLATFORM_SRC_OBJECTS_2 = \ basedll_msw_utils.o \ basedll_utilsexc.o \ basedll_fswatcher.o \ - basedll_msw_secretstore.o + basedll_msw_secretstore.o \ + basedll_msw_uilocale.o @COND_PLATFORM_WIN32_1@__BASE_PLATFORM_SRC_OBJECTS_2 = $(COND_PLATFORM_WIN32_1___BASE_PLATFORM_SRC_OBJECTS_2) @COND_PLATFORM_WIN32_1@__BASE_AND_GUI_PLATFORM_SRC_OBJECTS_2 \ @COND_PLATFORM_WIN32_1@ = basedll_main.o basedll_volume.o @@ -8380,6 +8407,7 @@ COND_PLATFORM_MACOSX_1___BASE_PLATFORM_SRC_OBJECTS_3 = \ baselib_strconv_cf.o \ baselib_utils_base.o \ baselib_core_secretstore.o \ + baselib_core_uilocale.o \ baselib_fdiodispatcher.o \ baselib_selectdispatcher.o \ baselib_appunix.o \ @@ -8417,7 +8445,8 @@ COND_PLATFORM_UNIX_1___BASE_PLATFORM_SRC_OBJECTS_3 = \ baselib_unix_mimetype.o \ baselib_fswatcher_inotify.o \ baselib_unix_stdpaths.o \ - baselib_unix_secretstore.o + baselib_unix_secretstore.o \ + baselib_unix_uilocale.o @COND_PLATFORM_UNIX_1@__BASE_PLATFORM_SRC_OBJECTS_3 = $(COND_PLATFORM_UNIX_1___BASE_PLATFORM_SRC_OBJECTS_3) COND_PLATFORM_WIN32_1___BASE_PLATFORM_SRC_OBJECTS_3 = \ baselib_basemsw.o \ @@ -8439,7 +8468,8 @@ COND_PLATFORM_WIN32_1___BASE_PLATFORM_SRC_OBJECTS_3 = \ baselib_msw_utils.o \ baselib_utilsexc.o \ baselib_fswatcher.o \ - baselib_msw_secretstore.o + baselib_msw_secretstore.o \ + baselib_msw_uilocale.o @COND_PLATFORM_WIN32_1@__BASE_PLATFORM_SRC_OBJECTS_3 = $(COND_PLATFORM_WIN32_1___BASE_PLATFORM_SRC_OBJECTS_3) @COND_PLATFORM_WIN32_1@__BASE_AND_GUI_PLATFORM_SRC_OBJECTS_3 \ @COND_PLATFORM_WIN32_1@ = baselib_main.o baselib_volume.o @@ -15995,6 +16025,9 @@ monodll_common_secretstore.o: $(srcdir)/src/common/secretstore.cpp $(MONODLL_ODE monodll_lzmastream.o: $(srcdir)/src/common/lzmastream.cpp $(MONODLL_ODEP) $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/common/lzmastream.cpp +monodll_common_uilocale.o: $(srcdir)/src/common/uilocale.cpp $(MONODLL_ODEP) + $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/common/uilocale.cpp + monodll_unix_mimetype.o: $(srcdir)/src/unix/mimetype.cpp $(MONODLL_ODEP) $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/unix/mimetype.cpp @@ -16007,6 +16040,9 @@ monodll_unix_stdpaths.o: $(srcdir)/src/unix/stdpaths.cpp $(MONODLL_ODEP) monodll_unix_secretstore.o: $(srcdir)/src/unix/secretstore.cpp $(MONODLL_ODEP) $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/unix/secretstore.cpp +monodll_unix_uilocale.o: $(srcdir)/src/unix/uilocale.cpp $(MONODLL_ODEP) + $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/unix/uilocale.cpp + monodll_basemsw.o: $(srcdir)/src/msw/basemsw.cpp $(MONODLL_ODEP) $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/msw/basemsw.cpp @@ -16067,6 +16103,9 @@ monodll_fswatcher.o: $(srcdir)/src/msw/fswatcher.cpp $(MONODLL_ODEP) monodll_msw_secretstore.o: $(srcdir)/src/msw/secretstore.cpp $(MONODLL_ODEP) $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/msw/secretstore.cpp +monodll_msw_uilocale.o: $(srcdir)/src/msw/uilocale.cpp $(MONODLL_ODEP) + $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/msw/uilocale.cpp + monodll_core_mimetype.o: $(srcdir)/src/osx/core/mimetype.cpp $(MONODLL_ODEP) $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/osx/core/mimetype.cpp @@ -16085,6 +16124,9 @@ monodll_utils_base.o: $(srcdir)/src/osx/cocoa/utils_base.mm $(MONODLL_ODEP) monodll_core_secretstore.o: $(srcdir)/src/osx/core/secretstore.cpp $(MONODLL_ODEP) $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/osx/core/secretstore.cpp +monodll_core_uilocale.o: $(srcdir)/src/osx/core/uilocale.cpp $(MONODLL_ODEP) + $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/osx/core/uilocale.cpp + monodll_fswatcher_fsevents.o: $(srcdir)/src/osx/fswatcher_fsevents.cpp $(MONODLL_ODEP) $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/osx/fswatcher_fsevents.cpp @@ -21272,6 +21314,9 @@ monolib_common_secretstore.o: $(srcdir)/src/common/secretstore.cpp $(MONOLIB_ODE monolib_lzmastream.o: $(srcdir)/src/common/lzmastream.cpp $(MONOLIB_ODEP) $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/common/lzmastream.cpp +monolib_common_uilocale.o: $(srcdir)/src/common/uilocale.cpp $(MONOLIB_ODEP) + $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/common/uilocale.cpp + monolib_unix_mimetype.o: $(srcdir)/src/unix/mimetype.cpp $(MONOLIB_ODEP) $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/unix/mimetype.cpp @@ -21284,6 +21329,9 @@ monolib_unix_stdpaths.o: $(srcdir)/src/unix/stdpaths.cpp $(MONOLIB_ODEP) monolib_unix_secretstore.o: $(srcdir)/src/unix/secretstore.cpp $(MONOLIB_ODEP) $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/unix/secretstore.cpp +monolib_unix_uilocale.o: $(srcdir)/src/unix/uilocale.cpp $(MONOLIB_ODEP) + $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/unix/uilocale.cpp + monolib_basemsw.o: $(srcdir)/src/msw/basemsw.cpp $(MONOLIB_ODEP) $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/msw/basemsw.cpp @@ -21344,6 +21392,9 @@ monolib_fswatcher.o: $(srcdir)/src/msw/fswatcher.cpp $(MONOLIB_ODEP) monolib_msw_secretstore.o: $(srcdir)/src/msw/secretstore.cpp $(MONOLIB_ODEP) $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/msw/secretstore.cpp +monolib_msw_uilocale.o: $(srcdir)/src/msw/uilocale.cpp $(MONOLIB_ODEP) + $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/msw/uilocale.cpp + monolib_core_mimetype.o: $(srcdir)/src/osx/core/mimetype.cpp $(MONOLIB_ODEP) $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/osx/core/mimetype.cpp @@ -21362,6 +21413,9 @@ monolib_utils_base.o: $(srcdir)/src/osx/cocoa/utils_base.mm $(MONOLIB_ODEP) monolib_core_secretstore.o: $(srcdir)/src/osx/core/secretstore.cpp $(MONOLIB_ODEP) $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/osx/core/secretstore.cpp +monolib_core_uilocale.o: $(srcdir)/src/osx/core/uilocale.cpp $(MONOLIB_ODEP) + $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/osx/core/uilocale.cpp + monolib_fswatcher_fsevents.o: $(srcdir)/src/osx/fswatcher_fsevents.cpp $(MONOLIB_ODEP) $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/osx/fswatcher_fsevents.cpp @@ -26549,6 +26603,9 @@ basedll_common_secretstore.o: $(srcdir)/src/common/secretstore.cpp $(BASEDLL_ODE basedll_lzmastream.o: $(srcdir)/src/common/lzmastream.cpp $(BASEDLL_ODEP) $(CXXC) -c -o $@ $(BASEDLL_CXXFLAGS) $(srcdir)/src/common/lzmastream.cpp +basedll_common_uilocale.o: $(srcdir)/src/common/uilocale.cpp $(BASEDLL_ODEP) + $(CXXC) -c -o $@ $(BASEDLL_CXXFLAGS) $(srcdir)/src/common/uilocale.cpp + basedll_unix_mimetype.o: $(srcdir)/src/unix/mimetype.cpp $(BASEDLL_ODEP) $(CXXC) -c -o $@ $(BASEDLL_CXXFLAGS) $(srcdir)/src/unix/mimetype.cpp @@ -26561,6 +26618,9 @@ basedll_unix_stdpaths.o: $(srcdir)/src/unix/stdpaths.cpp $(BASEDLL_ODEP) basedll_unix_secretstore.o: $(srcdir)/src/unix/secretstore.cpp $(BASEDLL_ODEP) $(CXXC) -c -o $@ $(BASEDLL_CXXFLAGS) $(srcdir)/src/unix/secretstore.cpp +basedll_unix_uilocale.o: $(srcdir)/src/unix/uilocale.cpp $(BASEDLL_ODEP) + $(CXXC) -c -o $@ $(BASEDLL_CXXFLAGS) $(srcdir)/src/unix/uilocale.cpp + basedll_basemsw.o: $(srcdir)/src/msw/basemsw.cpp $(BASEDLL_ODEP) $(CXXC) -c -o $@ $(BASEDLL_CXXFLAGS) $(srcdir)/src/msw/basemsw.cpp @@ -26621,6 +26681,9 @@ basedll_fswatcher.o: $(srcdir)/src/msw/fswatcher.cpp $(BASEDLL_ODEP) basedll_msw_secretstore.o: $(srcdir)/src/msw/secretstore.cpp $(BASEDLL_ODEP) $(CXXC) -c -o $@ $(BASEDLL_CXXFLAGS) $(srcdir)/src/msw/secretstore.cpp +basedll_msw_uilocale.o: $(srcdir)/src/msw/uilocale.cpp $(BASEDLL_ODEP) + $(CXXC) -c -o $@ $(BASEDLL_CXXFLAGS) $(srcdir)/src/msw/uilocale.cpp + basedll_core_mimetype.o: $(srcdir)/src/osx/core/mimetype.cpp $(BASEDLL_ODEP) $(CXXC) -c -o $@ $(BASEDLL_CXXFLAGS) $(srcdir)/src/osx/core/mimetype.cpp @@ -26639,6 +26702,9 @@ basedll_utils_base.o: $(srcdir)/src/osx/cocoa/utils_base.mm $(BASEDLL_ODEP) basedll_core_secretstore.o: $(srcdir)/src/osx/core/secretstore.cpp $(BASEDLL_ODEP) $(CXXC) -c -o $@ $(BASEDLL_CXXFLAGS) $(srcdir)/src/osx/core/secretstore.cpp +basedll_core_uilocale.o: $(srcdir)/src/osx/core/uilocale.cpp $(BASEDLL_ODEP) + $(CXXC) -c -o $@ $(BASEDLL_CXXFLAGS) $(srcdir)/src/osx/core/uilocale.cpp + basedll_fswatcher_fsevents.o: $(srcdir)/src/osx/fswatcher_fsevents.cpp $(BASEDLL_ODEP) $(CXXC) -c -o $@ $(BASEDLL_CXXFLAGS) $(srcdir)/src/osx/fswatcher_fsevents.cpp @@ -27023,6 +27089,9 @@ baselib_common_secretstore.o: $(srcdir)/src/common/secretstore.cpp $(BASELIB_ODE baselib_lzmastream.o: $(srcdir)/src/common/lzmastream.cpp $(BASELIB_ODEP) $(CXXC) -c -o $@ $(BASELIB_CXXFLAGS) $(srcdir)/src/common/lzmastream.cpp +baselib_common_uilocale.o: $(srcdir)/src/common/uilocale.cpp $(BASELIB_ODEP) + $(CXXC) -c -o $@ $(BASELIB_CXXFLAGS) $(srcdir)/src/common/uilocale.cpp + baselib_unix_mimetype.o: $(srcdir)/src/unix/mimetype.cpp $(BASELIB_ODEP) $(CXXC) -c -o $@ $(BASELIB_CXXFLAGS) $(srcdir)/src/unix/mimetype.cpp @@ -27035,6 +27104,9 @@ baselib_unix_stdpaths.o: $(srcdir)/src/unix/stdpaths.cpp $(BASELIB_ODEP) baselib_unix_secretstore.o: $(srcdir)/src/unix/secretstore.cpp $(BASELIB_ODEP) $(CXXC) -c -o $@ $(BASELIB_CXXFLAGS) $(srcdir)/src/unix/secretstore.cpp +baselib_unix_uilocale.o: $(srcdir)/src/unix/uilocale.cpp $(BASELIB_ODEP) + $(CXXC) -c -o $@ $(BASELIB_CXXFLAGS) $(srcdir)/src/unix/uilocale.cpp + baselib_basemsw.o: $(srcdir)/src/msw/basemsw.cpp $(BASELIB_ODEP) $(CXXC) -c -o $@ $(BASELIB_CXXFLAGS) $(srcdir)/src/msw/basemsw.cpp @@ -27095,6 +27167,9 @@ baselib_fswatcher.o: $(srcdir)/src/msw/fswatcher.cpp $(BASELIB_ODEP) baselib_msw_secretstore.o: $(srcdir)/src/msw/secretstore.cpp $(BASELIB_ODEP) $(CXXC) -c -o $@ $(BASELIB_CXXFLAGS) $(srcdir)/src/msw/secretstore.cpp +baselib_msw_uilocale.o: $(srcdir)/src/msw/uilocale.cpp $(BASELIB_ODEP) + $(CXXC) -c -o $@ $(BASELIB_CXXFLAGS) $(srcdir)/src/msw/uilocale.cpp + baselib_core_mimetype.o: $(srcdir)/src/osx/core/mimetype.cpp $(BASELIB_ODEP) $(CXXC) -c -o $@ $(BASELIB_CXXFLAGS) $(srcdir)/src/osx/core/mimetype.cpp @@ -27113,6 +27188,9 @@ baselib_utils_base.o: $(srcdir)/src/osx/cocoa/utils_base.mm $(BASELIB_ODEP) baselib_core_secretstore.o: $(srcdir)/src/osx/core/secretstore.cpp $(BASELIB_ODEP) $(CXXC) -c -o $@ $(BASELIB_CXXFLAGS) $(srcdir)/src/osx/core/secretstore.cpp +baselib_core_uilocale.o: $(srcdir)/src/osx/core/uilocale.cpp $(BASELIB_ODEP) + $(CXXC) -c -o $@ $(BASELIB_CXXFLAGS) $(srcdir)/src/osx/core/uilocale.cpp + baselib_fswatcher_fsevents.o: $(srcdir)/src/osx/fswatcher_fsevents.cpp $(BASELIB_ODEP) $(CXXC) -c -o $@ $(BASELIB_CXXFLAGS) $(srcdir)/src/osx/fswatcher_fsevents.cpp diff --git a/build/bakefiles/files.bkl b/build/bakefiles/files.bkl index ab4f770305..afa23f0bcc 100644 --- a/build/bakefiles/files.bkl +++ b/build/bakefiles/files.bkl @@ -115,6 +115,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! src/unix/fswatcher_inotify.cpp src/unix/stdpaths.cpp src/unix/secretstore.cpp + src/unix/uilocale.cpp $(BASE_UNIX_AND_DARWIN_NOTWXMAC_HDR) @@ -146,6 +147,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! src/msw/utilsexc.cpp src/msw/fswatcher.cpp src/msw/secretstore.cpp + src/msw/uilocale.cpp src/msw/main.cpp @@ -187,6 +189,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! src/osx/core/strconv_cf.cpp src/osx/cocoa/utils_base.mm src/osx/core/secretstore.cpp + src/osx/core/uilocale.cpp wx/osx/core/cfdataref.h @@ -561,6 +564,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! src/generic/fswatcherg.cpp src/common/secretstore.cpp src/common/lzmastream.cpp + src/common/uilocale.cpp src/common/event.cpp @@ -735,6 +739,8 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! wx/generic/fswatcher.h wx/secretstore.h wx/lzmastream.h + wx/localedefs.h + wx/uilocale.h diff --git a/build/cmake/files.cmake b/build/cmake/files.cmake index 3b90eda592..df46473e51 100644 --- a/build/cmake/files.cmake +++ b/build/cmake/files.cmake @@ -47,6 +47,7 @@ set(BASE_UNIX_SRC src/unix/fswatcher_inotify.cpp src/unix/secretstore.cpp src/unix/stdpaths.cpp + src/unix/uilocale.cpp ) set(BASE_UNIX_HDR @@ -76,6 +77,7 @@ set(BASE_WIN32_SRC src/msw/utils.cpp src/msw/utilsexc.cpp src/msw/fswatcher.cpp + src/msw/uilocale.cpp ) set(BASE_AND_GUI_WIN32_SRC @@ -114,6 +116,7 @@ set(BASE_COREFOUNDATION_SRC src/osx/core/secretstore.cpp src/osx/core/strconv_cf.cpp src/osx/cocoa/utils_base.mm + src/osx/core/uilocale.cpp ) set(BASE_COREFOUNDATION_HDR @@ -475,6 +478,7 @@ set(BASE_CMN_SRC src/common/fswatchercmn.cpp src/generic/fswatcherg.cpp src/common/lzmastream.cpp + src/common/uilocale.cpp ) set(BASE_AND_GUI_CMN_SRC @@ -651,6 +655,8 @@ set(BASE_CMN_HDR wx/fswatcher.h wx/generic/fswatcher.h wx/lzmastream.h + wx/localedefs.h + wx/uilocale.h ) set(NET_UNIX_SRC diff --git a/build/files b/build/files index 5c68b80c8d..eafe03673d 100644 --- a/build/files +++ b/build/files @@ -71,6 +71,7 @@ BASE_UNIX_SRC = src/unix/fswatcher_inotify.cpp src/unix/secretstore.cpp src/unix/stdpaths.cpp + src/unix/uilocale.cpp BASE_UNIX_HDR = $(BASE_UNIX_AND_DARWIN_NOTWXMAC_HDR) @@ -98,6 +99,7 @@ BASE_WIN32_SRC = src/msw/stdpaths.cpp src/msw/thread.cpp src/msw/timer.cpp + src/msw/uilocale.cpp src/msw/utils.cpp src/msw/utilsexc.cpp src/msw/fswatcher.cpp @@ -139,6 +141,7 @@ BASE_COREFOUNDATION_SRC = src/osx/core/evtloop_cf.cpp src/osx/core/secretstore.cpp src/osx/core/strconv_cf.cpp + src/osx/core/uilocale.cpp src/osx/cocoa/utils_base.mm BASE_COREFOUNDATION_HDR = @@ -481,6 +484,7 @@ BASE_CMN_SRC = src/common/tokenzr.cpp src/common/translation.cpp src/common/txtstrm.cpp + src/common/uilocale.cpp src/common/unichar.cpp src/common/uri.cpp src/common/ustring.cpp @@ -574,6 +578,7 @@ BASE_CMN_HDR = wx/link.h wx/list.h wx/listimpl.cpp + wx/localedefs.h wx/log.h wx/longlong.h wx/lzmastream.h @@ -632,6 +637,7 @@ BASE_CMN_HDR = wx/txtstrm.h wx/typeinfo.h wx/types.h + wx/uilocale.h wx/unichar.h wx/uri.h wx/ustring.h diff --git a/build/msw/makefile.gcc b/build/msw/makefile.gcc index 4ed7edba02..fcb8ae9aa3 100644 --- a/build/msw/makefile.gcc +++ b/build/msw/makefile.gcc @@ -477,6 +477,7 @@ MONODLL_OBJECTS = \ $(OBJS)\monodll_fswatcherg.o \ $(OBJS)\monodll_common_secretstore.o \ $(OBJS)\monodll_lzmastream.o \ + $(OBJS)\monodll_common_uilocale.o \ $(OBJS)\monodll_basemsw.o \ $(OBJS)\monodll_crashrpt.o \ $(OBJS)\monodll_debughlp.o \ @@ -497,6 +498,7 @@ MONODLL_OBJECTS = \ $(OBJS)\monodll_utilsexc.o \ $(OBJS)\monodll_fswatcher.o \ $(OBJS)\monodll_msw_secretstore.o \ + $(OBJS)\monodll_msw_uilocale.o \ $(OBJS)\monodll_event.o \ $(OBJS)\monodll_fs_mem.o \ $(OBJS)\monodll_msgout.o \ @@ -633,6 +635,7 @@ MONOLIB_OBJECTS = \ $(OBJS)\monolib_fswatcherg.o \ $(OBJS)\monolib_common_secretstore.o \ $(OBJS)\monolib_lzmastream.o \ + $(OBJS)\monolib_common_uilocale.o \ $(OBJS)\monolib_basemsw.o \ $(OBJS)\monolib_crashrpt.o \ $(OBJS)\monolib_debughlp.o \ @@ -653,6 +656,7 @@ MONOLIB_OBJECTS = \ $(OBJS)\monolib_utilsexc.o \ $(OBJS)\monolib_fswatcher.o \ $(OBJS)\monolib_msw_secretstore.o \ + $(OBJS)\monolib_msw_uilocale.o \ $(OBJS)\monolib_event.o \ $(OBJS)\monolib_fs_mem.o \ $(OBJS)\monolib_msgout.o \ @@ -783,6 +787,7 @@ BASEDLL_OBJECTS = \ $(OBJS)\basedll_fswatcherg.o \ $(OBJS)\basedll_common_secretstore.o \ $(OBJS)\basedll_lzmastream.o \ + $(OBJS)\basedll_common_uilocale.o \ $(OBJS)\basedll_basemsw.o \ $(OBJS)\basedll_crashrpt.o \ $(OBJS)\basedll_debughlp.o \ @@ -803,6 +808,7 @@ BASEDLL_OBJECTS = \ $(OBJS)\basedll_utilsexc.o \ $(OBJS)\basedll_fswatcher.o \ $(OBJS)\basedll_msw_secretstore.o \ + $(OBJS)\basedll_msw_uilocale.o \ $(OBJS)\basedll_event.o \ $(OBJS)\basedll_fs_mem.o \ $(OBJS)\basedll_msgout.o \ @@ -914,6 +920,7 @@ BASELIB_OBJECTS = \ $(OBJS)\baselib_fswatcherg.o \ $(OBJS)\baselib_common_secretstore.o \ $(OBJS)\baselib_lzmastream.o \ + $(OBJS)\baselib_common_uilocale.o \ $(OBJS)\baselib_basemsw.o \ $(OBJS)\baselib_crashrpt.o \ $(OBJS)\baselib_debughlp.o \ @@ -934,6 +941,7 @@ BASELIB_OBJECTS = \ $(OBJS)\baselib_utilsexc.o \ $(OBJS)\baselib_fswatcher.o \ $(OBJS)\baselib_msw_secretstore.o \ + $(OBJS)\baselib_msw_uilocale.o \ $(OBJS)\baselib_event.o \ $(OBJS)\baselib_fs_mem.o \ $(OBJS)\baselib_msgout.o \ @@ -7144,6 +7152,9 @@ $(OBJS)\monodll_common_secretstore.o: ../../src/common/secretstore.cpp $(OBJS)\monodll_lzmastream.o: ../../src/common/lzmastream.cpp $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< +$(OBJS)\monodll_common_uilocale.o: ../../src/common/uilocale.cpp + $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< + $(OBJS)\monodll_basemsw.o: ../../src/msw/basemsw.cpp $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< @@ -7204,6 +7215,9 @@ $(OBJS)\monodll_fswatcher.o: ../../src/msw/fswatcher.cpp $(OBJS)\monodll_msw_secretstore.o: ../../src/msw/secretstore.cpp $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< +$(OBJS)\monodll_msw_uilocale.o: ../../src/msw/uilocale.cpp + $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< + $(OBJS)\monodll_event.o: ../../src/common/event.cpp $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< @@ -9712,6 +9726,9 @@ $(OBJS)\monolib_common_secretstore.o: ../../src/common/secretstore.cpp $(OBJS)\monolib_lzmastream.o: ../../src/common/lzmastream.cpp $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< +$(OBJS)\monolib_common_uilocale.o: ../../src/common/uilocale.cpp + $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< + $(OBJS)\monolib_basemsw.o: ../../src/msw/basemsw.cpp $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< @@ -9772,6 +9789,9 @@ $(OBJS)\monolib_fswatcher.o: ../../src/msw/fswatcher.cpp $(OBJS)\monolib_msw_secretstore.o: ../../src/msw/secretstore.cpp $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< +$(OBJS)\monolib_msw_uilocale.o: ../../src/msw/uilocale.cpp + $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< + $(OBJS)\monolib_event.o: ../../src/common/event.cpp $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< @@ -12280,6 +12300,9 @@ $(OBJS)\basedll_common_secretstore.o: ../../src/common/secretstore.cpp $(OBJS)\basedll_lzmastream.o: ../../src/common/lzmastream.cpp $(CXX) -c -o $@ $(BASEDLL_CXXFLAGS) $(CPPDEPS) $< +$(OBJS)\basedll_common_uilocale.o: ../../src/common/uilocale.cpp + $(CXX) -c -o $@ $(BASEDLL_CXXFLAGS) $(CPPDEPS) $< + $(OBJS)\basedll_basemsw.o: ../../src/msw/basemsw.cpp $(CXX) -c -o $@ $(BASEDLL_CXXFLAGS) $(CPPDEPS) $< @@ -12340,6 +12363,9 @@ $(OBJS)\basedll_fswatcher.o: ../../src/msw/fswatcher.cpp $(OBJS)\basedll_msw_secretstore.o: ../../src/msw/secretstore.cpp $(CXX) -c -o $@ $(BASEDLL_CXXFLAGS) $(CPPDEPS) $< +$(OBJS)\basedll_msw_uilocale.o: ../../src/msw/uilocale.cpp + $(CXX) -c -o $@ $(BASEDLL_CXXFLAGS) $(CPPDEPS) $< + $(OBJS)\basedll_event.o: ../../src/common/event.cpp $(CXX) -c -o $@ $(BASEDLL_CXXFLAGS) $(CPPDEPS) $< @@ -12625,6 +12651,9 @@ $(OBJS)\baselib_common_secretstore.o: ../../src/common/secretstore.cpp $(OBJS)\baselib_lzmastream.o: ../../src/common/lzmastream.cpp $(CXX) -c -o $@ $(BASELIB_CXXFLAGS) $(CPPDEPS) $< +$(OBJS)\baselib_common_uilocale.o: ../../src/common/uilocale.cpp + $(CXX) -c -o $@ $(BASELIB_CXXFLAGS) $(CPPDEPS) $< + $(OBJS)\baselib_basemsw.o: ../../src/msw/basemsw.cpp $(CXX) -c -o $@ $(BASELIB_CXXFLAGS) $(CPPDEPS) $< @@ -12685,6 +12714,9 @@ $(OBJS)\baselib_fswatcher.o: ../../src/msw/fswatcher.cpp $(OBJS)\baselib_msw_secretstore.o: ../../src/msw/secretstore.cpp $(CXX) -c -o $@ $(BASELIB_CXXFLAGS) $(CPPDEPS) $< +$(OBJS)\baselib_msw_uilocale.o: ../../src/msw/uilocale.cpp + $(CXX) -c -o $@ $(BASELIB_CXXFLAGS) $(CPPDEPS) $< + $(OBJS)\baselib_event.o: ../../src/common/event.cpp $(CXX) -c -o $@ $(BASELIB_CXXFLAGS) $(CPPDEPS) $< diff --git a/build/msw/makefile.vc b/build/msw/makefile.vc index d8557a9f40..42d2c0634e 100644 --- a/build/msw/makefile.vc +++ b/build/msw/makefile.vc @@ -510,6 +510,7 @@ MONODLL_OBJECTS = \ $(OBJS)\monodll_fswatcherg.obj \ $(OBJS)\monodll_common_secretstore.obj \ $(OBJS)\monodll_lzmastream.obj \ + $(OBJS)\monodll_common_uilocale.obj \ $(OBJS)\monodll_basemsw.obj \ $(OBJS)\monodll_crashrpt.obj \ $(OBJS)\monodll_debughlp.obj \ @@ -530,6 +531,7 @@ MONODLL_OBJECTS = \ $(OBJS)\monodll_utilsexc.obj \ $(OBJS)\monodll_fswatcher.obj \ $(OBJS)\monodll_msw_secretstore.obj \ + $(OBJS)\monodll_msw_uilocale.obj \ $(OBJS)\monodll_event.obj \ $(OBJS)\monodll_fs_mem.obj \ $(OBJS)\monodll_msgout.obj \ @@ -675,6 +677,7 @@ MONOLIB_OBJECTS = \ $(OBJS)\monolib_fswatcherg.obj \ $(OBJS)\monolib_common_secretstore.obj \ $(OBJS)\monolib_lzmastream.obj \ + $(OBJS)\monolib_common_uilocale.obj \ $(OBJS)\monolib_basemsw.obj \ $(OBJS)\monolib_crashrpt.obj \ $(OBJS)\monolib_debughlp.obj \ @@ -695,6 +698,7 @@ MONOLIB_OBJECTS = \ $(OBJS)\monolib_utilsexc.obj \ $(OBJS)\monolib_fswatcher.obj \ $(OBJS)\monolib_msw_secretstore.obj \ + $(OBJS)\monolib_msw_uilocale.obj \ $(OBJS)\monolib_event.obj \ $(OBJS)\monolib_fs_mem.obj \ $(OBJS)\monolib_msgout.obj \ @@ -834,6 +838,7 @@ BASEDLL_OBJECTS = \ $(OBJS)\basedll_fswatcherg.obj \ $(OBJS)\basedll_common_secretstore.obj \ $(OBJS)\basedll_lzmastream.obj \ + $(OBJS)\basedll_common_uilocale.obj \ $(OBJS)\basedll_basemsw.obj \ $(OBJS)\basedll_crashrpt.obj \ $(OBJS)\basedll_debughlp.obj \ @@ -854,6 +859,7 @@ BASEDLL_OBJECTS = \ $(OBJS)\basedll_utilsexc.obj \ $(OBJS)\basedll_fswatcher.obj \ $(OBJS)\basedll_msw_secretstore.obj \ + $(OBJS)\basedll_msw_uilocale.obj \ $(OBJS)\basedll_event.obj \ $(OBJS)\basedll_fs_mem.obj \ $(OBJS)\basedll_msgout.obj \ @@ -977,6 +983,7 @@ BASELIB_OBJECTS = \ $(OBJS)\baselib_fswatcherg.obj \ $(OBJS)\baselib_common_secretstore.obj \ $(OBJS)\baselib_lzmastream.obj \ + $(OBJS)\baselib_common_uilocale.obj \ $(OBJS)\baselib_basemsw.obj \ $(OBJS)\baselib_crashrpt.obj \ $(OBJS)\baselib_debughlp.obj \ @@ -997,6 +1004,7 @@ BASELIB_OBJECTS = \ $(OBJS)\baselib_utilsexc.obj \ $(OBJS)\baselib_fswatcher.obj \ $(OBJS)\baselib_msw_secretstore.obj \ + $(OBJS)\baselib_msw_uilocale.obj \ $(OBJS)\baselib_event.obj \ $(OBJS)\baselib_fs_mem.obj \ $(OBJS)\baselib_msgout.obj \ @@ -7575,6 +7583,9 @@ $(OBJS)\monodll_common_secretstore.obj: ..\..\src\common\secretstore.cpp $(OBJS)\monodll_lzmastream.obj: ..\..\src\common\lzmastream.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\common\lzmastream.cpp +$(OBJS)\monodll_common_uilocale.obj: ..\..\src\common\uilocale.cpp + $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\common\uilocale.cpp + $(OBJS)\monodll_basemsw.obj: ..\..\src\msw\basemsw.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\msw\basemsw.cpp @@ -7635,6 +7646,9 @@ $(OBJS)\monodll_fswatcher.obj: ..\..\src\msw\fswatcher.cpp $(OBJS)\monodll_msw_secretstore.obj: ..\..\src\msw\secretstore.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\msw\secretstore.cpp +$(OBJS)\monodll_msw_uilocale.obj: ..\..\src\msw\uilocale.cpp + $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\msw\uilocale.cpp + $(OBJS)\monodll_event.obj: ..\..\src\common\event.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\common\event.cpp @@ -10143,6 +10157,9 @@ $(OBJS)\monolib_common_secretstore.obj: ..\..\src\common\secretstore.cpp $(OBJS)\monolib_lzmastream.obj: ..\..\src\common\lzmastream.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\common\lzmastream.cpp +$(OBJS)\monolib_common_uilocale.obj: ..\..\src\common\uilocale.cpp + $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\common\uilocale.cpp + $(OBJS)\monolib_basemsw.obj: ..\..\src\msw\basemsw.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\msw\basemsw.cpp @@ -10203,6 +10220,9 @@ $(OBJS)\monolib_fswatcher.obj: ..\..\src\msw\fswatcher.cpp $(OBJS)\monolib_msw_secretstore.obj: ..\..\src\msw\secretstore.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\msw\secretstore.cpp +$(OBJS)\monolib_msw_uilocale.obj: ..\..\src\msw\uilocale.cpp + $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\msw\uilocale.cpp + $(OBJS)\monolib_event.obj: ..\..\src\common\event.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\common\event.cpp @@ -12711,6 +12731,9 @@ $(OBJS)\basedll_common_secretstore.obj: ..\..\src\common\secretstore.cpp $(OBJS)\basedll_lzmastream.obj: ..\..\src\common\lzmastream.cpp $(CXX) /c /nologo /TP /Fo$@ $(BASEDLL_CXXFLAGS) ..\..\src\common\lzmastream.cpp +$(OBJS)\basedll_common_uilocale.obj: ..\..\src\common\uilocale.cpp + $(CXX) /c /nologo /TP /Fo$@ $(BASEDLL_CXXFLAGS) ..\..\src\common\uilocale.cpp + $(OBJS)\basedll_basemsw.obj: ..\..\src\msw\basemsw.cpp $(CXX) /c /nologo /TP /Fo$@ $(BASEDLL_CXXFLAGS) ..\..\src\msw\basemsw.cpp @@ -12771,6 +12794,9 @@ $(OBJS)\basedll_fswatcher.obj: ..\..\src\msw\fswatcher.cpp $(OBJS)\basedll_msw_secretstore.obj: ..\..\src\msw\secretstore.cpp $(CXX) /c /nologo /TP /Fo$@ $(BASEDLL_CXXFLAGS) ..\..\src\msw\secretstore.cpp +$(OBJS)\basedll_msw_uilocale.obj: ..\..\src\msw\uilocale.cpp + $(CXX) /c /nologo /TP /Fo$@ $(BASEDLL_CXXFLAGS) ..\..\src\msw\uilocale.cpp + $(OBJS)\basedll_event.obj: ..\..\src\common\event.cpp $(CXX) /c /nologo /TP /Fo$@ $(BASEDLL_CXXFLAGS) ..\..\src\common\event.cpp @@ -13056,6 +13082,9 @@ $(OBJS)\baselib_common_secretstore.obj: ..\..\src\common\secretstore.cpp $(OBJS)\baselib_lzmastream.obj: ..\..\src\common\lzmastream.cpp $(CXX) /c /nologo /TP /Fo$@ $(BASELIB_CXXFLAGS) ..\..\src\common\lzmastream.cpp +$(OBJS)\baselib_common_uilocale.obj: ..\..\src\common\uilocale.cpp + $(CXX) /c /nologo /TP /Fo$@ $(BASELIB_CXXFLAGS) ..\..\src\common\uilocale.cpp + $(OBJS)\baselib_basemsw.obj: ..\..\src\msw\basemsw.cpp $(CXX) /c /nologo /TP /Fo$@ $(BASELIB_CXXFLAGS) ..\..\src\msw\basemsw.cpp @@ -13116,6 +13145,9 @@ $(OBJS)\baselib_fswatcher.obj: ..\..\src\msw\fswatcher.cpp $(OBJS)\baselib_msw_secretstore.obj: ..\..\src\msw\secretstore.cpp $(CXX) /c /nologo /TP /Fo$@ $(BASELIB_CXXFLAGS) ..\..\src\msw\secretstore.cpp +$(OBJS)\baselib_msw_uilocale.obj: ..\..\src\msw\uilocale.cpp + $(CXX) /c /nologo /TP /Fo$@ $(BASELIB_CXXFLAGS) ..\..\src\msw\uilocale.cpp + $(OBJS)\baselib_event.obj: ..\..\src\common\event.cpp $(CXX) /c /nologo /TP /Fo$@ $(BASELIB_CXXFLAGS) ..\..\src\common\event.cpp diff --git a/build/msw/wx_base.vcxproj b/build/msw/wx_base.vcxproj index 102a6974d7..16a1d225c1 100644 --- a/build/msw/wx_base.vcxproj +++ b/build/msw/wx_base.vcxproj @@ -605,6 +605,26 @@ $(IntDir)common_%(Filename).obj + + $(IntDir)msw_%(Filename).obj + $(IntDir)msw_%(Filename).obj + $(IntDir)msw_%(Filename).obj + $(IntDir)msw_%(Filename).obj + $(IntDir)msw_%(Filename).obj + $(IntDir)msw_%(Filename).obj + $(IntDir)msw_%(Filename).obj + $(IntDir)msw_%(Filename).obj + + + $(IntDir)common_%(Filename).obj + $(IntDir)common_%(Filename).obj + $(IntDir)common_%(Filename).obj + $(IntDir)common_%(Filename).obj + $(IntDir)common_%(Filename).obj + $(IntDir)common_%(Filename).obj + $(IntDir)common_%(Filename).obj + $(IntDir)common_%(Filename).obj + @@ -823,6 +843,8 @@ + + diff --git a/build/msw/wx_base.vcxproj.filters b/build/msw/wx_base.vcxproj.filters index 44e8f07935..33a96e5ef0 100644 --- a/build/msw/wx_base.vcxproj.filters +++ b/build/msw/wx_base.vcxproj.filters @@ -261,6 +261,9 @@ Common Sources + + Common Sources + Common Sources @@ -360,6 +363,9 @@ MSW Sources + + MSW Sources + MSW Sources @@ -598,6 +604,9 @@ Common Headers + + Common Headers + Common Headers @@ -859,6 +868,9 @@ Common Headers + + Common Headers + Common Headers diff --git a/build/msw/wx_vc8_base.vcproj b/build/msw/wx_vc8_base.vcproj index 5708485856..feb02ea5e3 100644 --- a/build/msw/wx_vc8_base.vcproj +++ b/build/msw/wx_vc8_base.vcproj @@ -1249,6 +1249,74 @@ RelativePath="..\..\src\common\txtstrm.cpp" > + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1446,6 +1514,74 @@ RelativePath="..\..\src\msw\timer.cpp" > + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2103,6 +2239,10 @@ RelativePath="..\..\include\wx\list.h" > + + @@ -2343,6 +2483,10 @@ RelativePath="..\..\include\wx\types.h" > + + diff --git a/build/msw/wx_vc9_base.vcproj b/build/msw/wx_vc9_base.vcproj index 1accda8c00..33df8ce65f 100644 --- a/build/msw/wx_vc9_base.vcproj +++ b/build/msw/wx_vc9_base.vcproj @@ -1245,6 +1245,74 @@ RelativePath="..\..\src\common\txtstrm.cpp" > + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1442,6 +1510,74 @@ RelativePath="..\..\src\msw\timer.cpp" > + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2099,6 +2235,10 @@ RelativePath="..\..\include\wx\list.h" > + + @@ -2339,6 +2479,10 @@ RelativePath="..\..\include\wx\types.h" > + + diff --git a/include/wx/dvrenderers.h b/include/wx/dvrenderers.h index 85fcea0023..3b6857e971 100644 --- a/include/wx/dvrenderers.h +++ b/include/wx/dvrenderers.h @@ -527,6 +527,8 @@ public: virtual wxSize GetSize() const wxOVERRIDE; private: + wxString FormatDate() const; + wxDateTime m_date; }; #else // !wxUSE_DATEPICKCTRL diff --git a/include/wx/generic/spinctlg.h b/include/wx/generic/spinctlg.h index db7162751a..594a4d02ed 100644 --- a/include/wx/generic/spinctlg.h +++ b/include/wx/generic/spinctlg.h @@ -430,8 +430,6 @@ private: void DoSetDigitsAndUpdate(unsigned digits); - wxString m_format; - wxDECLARE_DYNAMIC_CLASS(wxSpinCtrlDouble); }; diff --git a/include/wx/intl.h b/include/wx/intl.h index 2ce148dd54..866bcfbcac 100644 --- a/include/wx/intl.h +++ b/include/wx/intl.h @@ -13,19 +13,10 @@ #define _WX_INTL_H_ #include "wx/defs.h" +#include "wx/localedefs.h" #include "wx/string.h" #include "wx/translation.h" -// Make wxLayoutDirection enum available without need for wxUSE_INTL so wxWindow, wxApp -// and other classes are not distrubed by wxUSE_INTL - -enum wxLayoutDirection -{ - wxLayout_Default, - wxLayout_LeftToRight, - wxLayout_RightToLeft -}; - #if wxUSE_INTL #include "wx/fontenc.h" @@ -50,86 +41,6 @@ class WXDLLIMPEXP_FWD_BASE wxLanguageInfoArray; // locale support // ============================================================================ -// ---------------------------------------------------------------------------- -// wxLanguageInfo: encapsulates wxLanguage to OS native lang.desc. -// translation information -// ---------------------------------------------------------------------------- - -struct WXDLLIMPEXP_BASE wxLanguageInfo -{ - int Language; // wxLanguage id - wxString CanonicalName; // Canonical name, e.g. fr_FR -#ifdef __WINDOWS__ - wxUint32 WinLang, // Win32 language identifiers - WinSublang; -#endif // __WINDOWS__ - wxString Description; // human-readable name of the language - wxLayoutDirection LayoutDirection; - -#ifdef __WINDOWS__ - // return the LCID corresponding to this language - wxUint32 GetLCID() const; -#endif // __WINDOWS__ - - // return the locale name corresponding to this language usable with - // setlocale() on the current system or empty string if this locale is not - // supported - wxString GetLocaleName() const; - - // Call setlocale() and return non-null value if it works for this language. - // - // This function is mostly for internal use, as changing locale involves - // more than just calling setlocale() on some platforms, use wxLocale to - // do everything that needs to be done instead of calling this method. - const char* TrySetLocale() const; -}; - -// ---------------------------------------------------------------------------- -// wxLocaleCategory: the category of locale settings -// ---------------------------------------------------------------------------- - -enum wxLocaleCategory -{ - // (any) numbers - wxLOCALE_CAT_NUMBER, - - // date/time - wxLOCALE_CAT_DATE, - - // monetary value - wxLOCALE_CAT_MONEY, - - // default category for wxLocaleInfo values which only apply to a single - // category (e.g. wxLOCALE_SHORT_DATE_FMT) - wxLOCALE_CAT_DEFAULT, - - wxLOCALE_CAT_MAX -}; - -// ---------------------------------------------------------------------------- -// wxLocaleInfo: the items understood by wxLocale::GetInfo() -// ---------------------------------------------------------------------------- - -enum wxLocaleInfo -{ - // the thousands separator (for wxLOCALE_CAT_NUMBER or MONEY) - wxLOCALE_THOUSANDS_SEP, - - // the character used as decimal point (for wxLOCALE_CAT_NUMBER or MONEY) - wxLOCALE_DECIMAL_POINT, - - // the stftime()-formats used for short/long date and time representations - // (under some platforms short and long date formats are the same) - // - // NB: these elements should appear in this order, code in GetInfo() relies - // on it - wxLOCALE_SHORT_DATE_FMT, - wxLOCALE_LONG_DATE_FMT, - wxLOCALE_DATE_TIME_FMT, - wxLOCALE_TIME_FMT - -}; - // ---------------------------------------------------------------------------- // wxLocale: encapsulates all language dependent settings, including current // message catalogs, date, time and currency formats (TODO) &c @@ -145,6 +56,8 @@ enum wxLocaleInitFlags #endif }; +// NOTE: This class is deprecated, use wxUILocale and wxTranslations instead. + class WXDLLIMPEXP_BASE wxLocale { public: diff --git a/include/wx/localedefs.h b/include/wx/localedefs.h new file mode 100644 index 0000000000..d5b43b2eff --- /dev/null +++ b/include/wx/localedefs.h @@ -0,0 +1,113 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/localedefs.h +// Purpose: Definitions of common locale-related constants and structs. +// Author: Vadim Zeitlin +// Created: 2021-07-31 (extracted from wx/intl.h) +// Copyright: (c) 2021 Vadim Zeitlin +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_LOCALEDEFS_H_ +#define _WX_LOCALEDEFS_H_ + +// ---------------------------------------------------------------------------- +// wxLayoutDirection: used by wxWindow, wxDC etc +// ---------------------------------------------------------------------------- + +// Note that this one must be available even when wxUSE_INTL == 0 as it's used +// outside of locale code too. + +enum wxLayoutDirection +{ + wxLayout_Default, + wxLayout_LeftToRight, + wxLayout_RightToLeft +}; + +#if wxUSE_INTL + +#include "wx/string.h" + +// ---------------------------------------------------------------------------- +// wxLocaleCategory: the category of locale settings +// ---------------------------------------------------------------------------- + +enum wxLocaleCategory +{ + // (any) numbers + wxLOCALE_CAT_NUMBER, + + // date/time + wxLOCALE_CAT_DATE, + + // monetary value + wxLOCALE_CAT_MONEY, + + // default category for wxLocaleInfo values which only apply to a single + // category (e.g. wxLOCALE_SHORT_DATE_FMT) + wxLOCALE_CAT_DEFAULT, + + wxLOCALE_CAT_MAX +}; + +// ---------------------------------------------------------------------------- +// wxLocaleInfo: the items understood by wxLocale::GetInfo() +// ---------------------------------------------------------------------------- + +enum wxLocaleInfo +{ + // the thousands separator (for wxLOCALE_CAT_NUMBER or MONEY) + wxLOCALE_THOUSANDS_SEP, + + // the character used as decimal point (for wxLOCALE_CAT_NUMBER or MONEY) + wxLOCALE_DECIMAL_POINT, + + // the stftime()-formats used for short/long date and time representations + // (under some platforms short and long date formats are the same) + // + // NB: these elements should appear in this order, code in GetInfo() relies + // on it + wxLOCALE_SHORT_DATE_FMT, + wxLOCALE_LONG_DATE_FMT, + wxLOCALE_DATE_TIME_FMT, + wxLOCALE_TIME_FMT + +}; + +// ---------------------------------------------------------------------------- +// wxLanguageInfo: encapsulates wxLanguage to OS native lang.desc. +// translation information +// ---------------------------------------------------------------------------- + +struct WXDLLIMPEXP_BASE wxLanguageInfo +{ + int Language; // wxLanguage id + wxString CanonicalName; // Canonical name, e.g. fr_FR +#ifdef __WINDOWS__ + wxUint32 WinLang, // Win32 language identifiers + WinSublang; +#endif // __WINDOWS__ + wxString Description; // human-readable name of the language + wxLayoutDirection LayoutDirection; + +#ifdef __WINDOWS__ + // return the LCID corresponding to this language + wxUint32 GetLCID() const; +#endif // __WINDOWS__ + + // return the locale name corresponding to this language usable with + // setlocale() on the current system or empty string if this locale is not + // supported + wxString GetLocaleName() const; + + // Call setlocale() and return non-null value if it works for this language. + // + // This function is mostly for internal use, as changing locale involves + // more than just calling setlocale() on some platforms, use wxLocale to + // do everything that needs to be done instead of calling this method. + const char* TrySetLocale() const; +}; + +#endif // wxUSE_INTL + +#endif // _WX_LOCALEDEFS_H_ diff --git a/include/wx/msw/private/uilocale.h b/include/wx/msw/private/uilocale.h new file mode 100644 index 0000000000..8684213610 --- /dev/null +++ b/include/wx/msw/private/uilocale.h @@ -0,0 +1,28 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/msw/private/uilocale.h +// Purpose: MSW-specific locale-related helpers +// Author: Vadim Zeitlin +// Created: 2021-08-14 +// Copyright: (c) 2021 Vadim Zeitlin +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_MSW_PRIVATE_UILOCALE_H_ +#define _WX_MSW_PRIVATE_UILOCALE_H_ + +#include "wx/msw/private.h" // Include to get LCID. + +#ifndef LOCALE_SNAME +#define LOCALE_SNAME 0x5c +#endif +#ifndef LOCALE_CUSTOM_UI_DEFAULT +#define LOCALE_CUSTOM_UI_DEFAULT 0x1400 +#endif + +// Use the specific LCID for the current thread. +void wxUseLCID(LCID lcid); + +// This function is defined in src/common/intl.cpp +wxString wxGetInfoFromLCID(LCID lcid, wxLocaleInfo index, wxLocaleCategory cat); + +#endif // _WX_MSW_PRIVATE_UILOCALE_H_ 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/include/wx/private/localeset.h b/include/wx/private/localeset.h new file mode 100644 index 0000000000..a977247d6b --- /dev/null +++ b/include/wx/private/localeset.h @@ -0,0 +1,49 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/private/localeset.h +// Purpose: Define helper wxLocaleSetter class. +// Author: Vadim Zeitlin +// Created: 2021-08-03 (extracted from tests/testprec.h) +// Copyright: (c) 2021 Vadim Zeitlin +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_PRIVATE_LOCALESET_H_ +#define _WX_PRIVATE_LOCALESET_H_ + +#include "wx/crt.h" // wxStrdupA() + +#include + +// Helper class setting the locale to the given one for its lifetime. +class wxLocaleSetter +{ +public: + wxLocaleSetter(const char *loc) + : m_locOld(wxStrdupA(setlocale(LC_ALL, NULL))) + { + setlocale(LC_ALL, loc); + } + + ~wxLocaleSetter() + { + setlocale(LC_ALL, m_locOld); + free(m_locOld); + } + +private: + char * const m_locOld; + + wxDECLARE_NO_COPY_CLASS(wxLocaleSetter); +}; + +// An even simpler helper for setting the locale to "C" one during its lifetime. +class wxCLocaleSetter : private wxLocaleSetter +{ +public: + wxCLocaleSetter() : wxLocaleSetter("C") { } + +private: + wxDECLARE_NO_COPY_CLASS(wxCLocaleSetter); +}; + +#endif // _WX_PRIVATE_LOCALESET_H_ diff --git a/include/wx/private/uilocale.h b/include/wx/private/uilocale.h new file mode 100644 index 0000000000..bfa6f318ea --- /dev/null +++ b/include/wx/private/uilocale.h @@ -0,0 +1,52 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/private/uilocale.h +// Purpose: wxUILocaleImpl class declaration +// Author: Vadim Zeitlin +// Created: 2021-08-01 +// Copyright: (c) 2021 Vadim Zeitlin +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_PRIVATE_UILOCALE_H_ +#define _WX_PRIVATE_UILOCALE_H_ + +#include "wx/localedefs.h" +#include "wx/string.h" + +// ---------------------------------------------------------------------------- +// wxUILocaleImpl provides the implementation of public wxUILocale functions +// ---------------------------------------------------------------------------- + +class wxUILocaleImpl +{ +public: + // This function is implemented in platform-specific code and returns the + // object used by default, i.e. if wxUILocale::UseDefault() is not called. + // This object corresponds to the traditional "C" locale. + // + // It should never return NULL. + static wxUILocaleImpl* CreateStdC(); + + // Similarly, this one returns the object corresponding to the default user + // locale settings which is used if wxUILocale::UseDefault() was called. + // + // It may return NULL in case of failure. + static wxUILocaleImpl* CreateUserDefault(); + + // This function exists only for wxLocale compatibility and sets the locale + // corresponding to the given language. + // + // The language passed to this function is a valid language, i.e. neither + // wxLANGUAGE_UNKNOWN nor wxLANGUAGE_DEFAULT. + // + // It may return NULL in case of failure. + static wxUILocaleImpl* CreateForLanguage(const wxLanguageInfo& info); + + // Functions corresponding to wxUILocale ones. + virtual wxString GetName() const = 0; + virtual wxString GetInfo(wxLocaleInfo index, wxLocaleCategory cat) const = 0; + + virtual ~wxUILocaleImpl() { } +}; + +#endif // _WX_PRIVATE_UILOCALE_H_ diff --git a/include/wx/uilocale.h b/include/wx/uilocale.h new file mode 100644 index 0000000000..acae223190 --- /dev/null +++ b/include/wx/uilocale.h @@ -0,0 +1,84 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/uilocale.h +// Purpose: wxUILocale class declaration. +// Author: Vadim Zeitlin +// Created: 2021-07-31 +// Copyright: (c) 2021 Vadim Zeitlin +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_UILOCALE_H_ +#define _WX_UILOCALE_H_ + +#include "wx/defs.h" + +#if wxUSE_INTL + +#include "wx/localedefs.h" +#include "wx/string.h" + +class wxUILocaleImpl; + +// ---------------------------------------------------------------------------- +// wxUILocale allows to use the default UI locale and get information about it +// ---------------------------------------------------------------------------- + +class WXDLLIMPEXP_BASE wxUILocale +{ +public: + // Configure the UI to use the default user locale. + static bool UseDefault(); + + // Use the locale corresponding to the given language. + // + // This is a compatibility function used by wxWidgets itself, don't use it + // in the new code. + static bool UseLanguage(const wxLanguageInfo& info); + + // Get the object corresponding to the currently used locale. + static const wxUILocale& GetCurrent(); + + // Get the platform-dependent name of the current locale. + wxString GetName() const; + + // Query the locale for the specified information. + wxString GetInfo(wxLocaleInfo index, + wxLocaleCategory cat = wxLOCALE_CAT_DEFAULT) const; + + // Note that this class is not supposed to be used polymorphically, hence + // its dtor is not virtual. + ~wxUILocale(); + +private: + // Ctor is private, use static accessor to get objects of this class. + wxUILocale() : m_impl(NULL) { } + + // Used by UseDefault(). + // + // Note that this object takes ownership of the provided pointer and will + // delete it in dtor. + void SetImpl(wxUILocaleImpl* impl); + + + static wxUILocale ms_current; + + wxUILocaleImpl* m_impl; + + wxDECLARE_NO_COPY_CLASS(wxUILocale); +}; + +inline wxString wxGetUIDateFormat() +{ + return wxUILocale::GetCurrent().GetInfo(wxLOCALE_SHORT_DATE_FMT); +} + +#else // !wxUSE_INTL + +inline wxString wxGetUIDateFormat() +{ + return wxString(wxS("%x")); +} + +#endif // wxUSE_INTL/!wxUSE_INTL + +#endif // _WX_UILOCALE_H_ diff --git a/include/wx/unix/private/uilocale.h b/include/wx/unix/private/uilocale.h new file mode 100644 index 0000000000..7a882810d0 --- /dev/null +++ b/include/wx/unix/private/uilocale.h @@ -0,0 +1,33 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/unix/private/uilocale.h +// Purpose: Various locale-related helpers used under Unix systems only +// Author: Vadim Zeitlin +// Created: 2021-08-14 (extracted from src/common/intl.cpp) +// Copyright: (c) 2021 Vadim Zeitlin +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_UNIX_PRIVATE_UILOCALE_H_ +#define _WX_UNIX_PRIVATE_UILOCALE_H_ + +#include "wx/string.h" + +// get just the language part ("en" in "en_GB") +inline wxString ExtractLang(const wxString& langFull) +{ + return langFull.BeforeFirst('_'); +} + +// get everything else (including the leading '_') +inline wxString ExtractNotLang(const wxString& langFull) +{ + size_t pos = langFull.find('_'); + if ( pos != wxString::npos ) + return langFull.substr(pos); + else + return wxString(); +} + +const char *wxSetlocaleTryAll(int c, const wxString& lc); + +#endif // _WX_UNIX_PRIVATE_UILOCALE_H_ diff --git a/interface/wx/intl.h b/interface/wx/intl.h index 92902c1b7d..92d1bab62d 100644 --- a/interface/wx/intl.h +++ b/interface/wx/intl.h @@ -69,7 +69,7 @@ struct wxLanguageInfo /** The category of locale settings. - @see wxLocale::GetInfo() + @see wxLocale::GetInfo(), wxUILocale::GetInfo() */ enum wxLocaleCategory { @@ -108,6 +108,8 @@ enum wxLocaleCategory All of these values are used with @c wxLOCALE_CAT_DATE in wxLocale::GetInfo() or, more typically, with @c wxLOCALE_CAT_DEFAULT as they only apply to a single category. + + @see wxUILocale::GetInfo() */ enum wxLocaleInfo { @@ -116,6 +118,9 @@ enum wxLocaleInfo This value can be used with either wxLOCALE_CAT_NUMBER or wxLOCALE_CAT_MONEY categories. + + By default, i.e. when wxLOCALE_CAT_DEFAULT is used, the separator for + numbers is returned. */ wxLOCALE_THOUSANDS_SEP, @@ -124,6 +129,9 @@ enum wxLocaleInfo This value can be used with either wxLOCALE_CAT_NUMBER or wxLOCALE_CAT_MONEY categories. + + By default, i.e. when wxLOCALE_CAT_DEFAULT is used, the decimal point + for numbers is returned. */ wxLOCALE_DECIMAL_POINT, @@ -166,6 +174,13 @@ enum wxLocaleInfo wxLocale class encapsulates all language-dependent settings and is a generalization of the C locale concept. + @note While this class can still be used in wxMSW and wxGTK ports, it + doesn't work in wxOSX where it is impossible to change the application + UI locale after launching it. Worse, since macOS 11 (Big Sur), using + wxLocale can break application display due to bugs in C locale support + in macOS itself. Because of this, it is recommended to use wxUILocale + instead of this class for the applications targeting macOS. + In wxWidgets this class manages current locale. It also initializes and activates wxTranslations object that manages message catalogs. @@ -435,6 +450,9 @@ public: /** Get the values of a locale datum in the OS locale. + This function shouldn't be used in the new code, use + wxUILocale::GetInfo() instead. + 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 diff --git a/interface/wx/numformatter.h b/interface/wx/numformatter.h index 1479bae1c4..f635e2327d 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). @@ -89,12 +93,22 @@ 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 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 +128,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 +137,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/interface/wx/uilocale.h b/interface/wx/uilocale.h new file mode 100644 index 0000000000..de6bcc7550 --- /dev/null +++ b/interface/wx/uilocale.h @@ -0,0 +1,121 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/uilocale.h +// Purpose: Interface of wxUILocale +// Author: Vadim Zeitlin +// Created: 2021-08-01 +// Copyright: (c) 2021 Vadim Zeitlin +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +/** + Query and modify locale used for the UI by the current platform. + + UI locale determines all culture-dependent conventions used in the user + interface, including numbers, currencies and dates formatting. It also + determines the language used by the native dialogs, such as wxFileDialog, + where different labels use the language corresponding to the current UI + locale. + + The UI locale is, in general, different from C locale set by the standard + @c setlocale() function and affecting C standard library functions such as + @c printf(), @c scanf(), @c strftime() and many others. Unfortunately, the + relationship between C and UI locales is not the same depending on the + platform: with wxGTK they must be the same, but under macOS C locale must + not be changed, as doing this exposes bugs in the system. Because of this, + applications can't generally count on C locale being set to any particular + value and it is best to avoid using it, including implicitly via the + standard C functions, in portable code. Instead, consider using + wxNumberFormatter for parsing and formatting numbers according to the + current UI locale or wxString::FromCDouble() and wxString::ToCDouble() + functions for doing it always using period as decimal separator. + + Localized applications should call wxUILocale::UseDefault() on startup to + explicitly indicate that they opt-in using the current UI locale, even if + this results in changing the global C locale, as is the case in wxGTK. Note + that some platforms (MSW and macOS) will use default user locale for their + standard dialogs even if this function is not called, but it is still + necessary to call it to use the correct number and date formats and to + avoid mixing messages in the user language with default formats not + corresponding to it. + + Please also note that under macOS to really use the user locale, it must be + listed as a supported language in the application @c Info.plist file under + @c CFBundleLocalizations key. + + Unlike wxLocale class, this class doesn't affect the translations used by + the application, see wxTranslations for doing this. + + @library{wxbase} + @since 3.1.6 + */ +class wxUILocale +{ +public: + /** + Configure the UI to use the default user locale. + + Localized applications should call this functions as early as possible + during the program startup, e.g. in the very beginning of the + overridden wxApp::OnInit(). + + Note that under most Unix systems (but not macOS) this function changes + the C locale to the locale specified by the environment variables and + so affects the results of calling C functions such as @c sprintf() etc + which can use comma, rather than period, as decimal separator. The + wxString::ToCDouble() and wxString::FromCDouble() functions can be used + for parsing and formatting floating point numbers using period as + decimal separator independently of the current locale. + + @return @true on success or @false if the default locale couldn't be set + */ + static bool UseDefault(); + + /** + Get the object corresponding to the currently used locale. + + If UseDefault() had been called, this object corresponds to the default + user locale. Otherwise it corresponds to a generic locale similar to + "C" locale, i.e. always uses period as decimal separator and m/d/y date + format. + */ + static const wxUILocale& GetCurrent(); + + /** + Get the platform-dependent name of the current locale. + + This name can be used in diagnostic messages. + */ + wxString GetName() const; + + /** + Query the locale for the specified information. + + This function returns the value of the locale-specific option specified + by the given @a index. + + @param index + One of the elements of wxLocaleInfo enum. + @param cat + The category to use with the given index or wxLOCALE_CAT_DEFAULT if + the index can only apply to a single category. + @return + The option value or empty string if the function failed. + */ + wxString GetInfo(wxLocaleInfo index, + wxLocaleCategory cat = wxLOCALE_CAT_DEFAULT) const; +}; + +/** + Return the format to use for formatting user-visible dates. + + This is a simple wrapper function normally calling wxUILocale::GetInfo() + with wxLOCALE_SHORT_DATE_FMT argument, but which is also available when @c + wxUSE_INTL==0, i.e. support for internationalization is disabled at + compile-time, in which case it returns @c %x string, i.e. uses the current + C locale formatting rather than UI locale. + + @see wxDateTime::Format() + + @since 3.1.6 + */ +wxString wxGetUIDateFormat(); diff --git a/samples/internat/internat.cpp b/samples/internat/internat.cpp index 5502619b53..15f8319239 100644 --- a/samples/internat/internat.cpp +++ b/samples/internat/internat.cpp @@ -28,11 +28,17 @@ #include "wx/wx.h" #endif +#include "wx/calctrl.h" #include "wx/intl.h" #include "wx/file.h" +#include "wx/grid.h" #include "wx/log.h" #include "wx/cmdline.h" +#include "wx/numformatter.h" #include "wx/platinfo.h" +#include "wx/spinctrl.h" +#include "wx/translation.h" +#include "wx/uilocale.h" #ifndef wxHAS_IMAGES_IN_RESOURCES #include "../sample.xpm" @@ -53,22 +59,29 @@ class MyApp: public wxApp { public: - MyApp() { m_lang = wxLANGUAGE_UNKNOWN; } + MyApp() { m_setLocale = Locale_Ask; } virtual void OnInitCmdLine(wxCmdLineParser& parser) wxOVERRIDE; virtual bool OnCmdLineParsed(wxCmdLineParser& parser) wxOVERRIDE; virtual bool OnInit() wxOVERRIDE; protected: - wxLanguage m_lang; // language specified by user - wxLocale m_locale; // locale we'll be using + // Specifies whether we should use the current locale or not. By default we + // ask the user about it, but it's possible to override this using the + // command line options. + enum + { + Locale_Ask, + Locale_Set, + Locale_Skip + } m_setLocale; }; // Define a new frame type class MyFrame: public wxFrame { public: - MyFrame(wxLocale& m_locale); + MyFrame(); public: void OnTestLocaleAvail(wxCommandEvent& event); @@ -80,14 +93,13 @@ public: void OnPlay(wxCommandEvent& event); void OnOpen(wxCommandEvent& event); + void OnSave(wxCommandEvent& event); void OnTest1(wxCommandEvent& event); void OnTest2(wxCommandEvent& event); void OnTest3(wxCommandEvent& event); void OnTestMsgBox(wxCommandEvent& event); wxDECLARE_EVENT_TABLE(); - - wxLocale& m_locale; }; // ---------------------------------------------------------------------------- @@ -114,59 +126,6 @@ enum INTERNAT_MACRO_9 }; -// language data -static const wxLanguage langIds[] = -{ - wxLANGUAGE_DEFAULT, - wxLANGUAGE_FRENCH, - wxLANGUAGE_ITALIAN, - wxLANGUAGE_GERMAN, - wxLANGUAGE_RUSSIAN, - wxLANGUAGE_BULGARIAN, - wxLANGUAGE_CZECH, - wxLANGUAGE_POLISH, - wxLANGUAGE_SWEDISH, -#if wxUSE_UNICODE || defined(__WXMOTIF__) - wxLANGUAGE_JAPANESE, -#endif -#if wxUSE_UNICODE - wxLANGUAGE_GEORGIAN, - wxLANGUAGE_ENGLISH, - wxLANGUAGE_ENGLISH_US, - wxLANGUAGE_ARABIC, - wxLANGUAGE_ARABIC_EGYPT -#endif -}; - -// note that it makes no sense to translate these strings, they are -// shown before we set the locale anyhow -const wxString langNames[] = -{ - "System default", - "French", - "Italian", - "German", - "Russian", - "Bulgarian", - "Czech", - "Polish", - "Swedish", -#if wxUSE_UNICODE || defined(__WXMOTIF__) - "Japanese", -#endif -#if wxUSE_UNICODE - "Georgian", - "English", - "English (U.S.)", - "Arabic", - "Arabic (Egypt)" -#endif -}; - -// the arrays must be in sync -wxCOMPILE_TIME_ASSERT( WXSIZEOF(langNames) == WXSIZEOF(langIds), - LangArraysMismatch ); - // ---------------------------------------------------------------------------- // wxWidgets macros // ---------------------------------------------------------------------------- @@ -181,6 +140,7 @@ wxBEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_MENU(INTERNAT_PLAY, MyFrame::OnPlay) EVT_MENU(wxID_OPEN, MyFrame::OnOpen) + EVT_MENU(wxID_SAVE, MyFrame::OnSave) EVT_MENU(INTERNAT_TEST_1, MyFrame::OnTest1) EVT_MENU(INTERNAT_TEST_2, MyFrame::OnTest2) EVT_MENU(INTERNAT_TEST_3, MyFrame::OnTest3) @@ -198,11 +158,16 @@ wxIMPLEMENT_APP(MyApp); // ---------------------------------------------------------------------------- // command line arguments handling + +static const char* OPTION_NO_LOCALE = "no-locale"; +static const char* OPTION_SET_LOCALE = "set-locale"; + void MyApp::OnInitCmdLine(wxCmdLineParser& parser) { - parser.AddParam(_("locale"), - wxCMD_LINE_VAL_STRING, - wxCMD_LINE_PARAM_OPTIONAL); + parser.AddSwitch("n", OPTION_NO_LOCALE, + _("skip setting locale on startup")); + parser.AddSwitch("y", OPTION_SET_LOCALE, + _("do set locale on startup without asking")); wxApp::OnInitCmdLine(parser); } @@ -212,17 +177,20 @@ bool MyApp::OnCmdLineParsed(wxCmdLineParser& parser) if ( !wxApp::OnCmdLineParsed(parser) ) return false; - if ( parser.GetParamCount() ) + if ( parser.Found(OPTION_NO_LOCALE) ) { - const wxString loc = parser.GetParam(); - const wxLanguageInfo * const lang = wxLocale::FindLanguageInfo(loc); - if ( !lang ) + m_setLocale = Locale_Skip; + } + + if ( parser.Found(OPTION_SET_LOCALE) ) + { + if ( m_setLocale == Locale_Skip ) { - wxLogError(_("Locale \"%s\" is unknown."), loc); - return false; + wxLogWarning("--%s option overrides --%s", + OPTION_SET_LOCALE, OPTION_NO_LOCALE); } - m_lang = static_cast(lang->Language); + m_setLocale = Locale_Set; } return true; @@ -234,57 +202,75 @@ bool MyApp::OnInit() if ( !wxApp::OnInit() ) return false; - if ( m_lang == wxLANGUAGE_UNKNOWN ) + // For demonstration purposes only, ask the user if they want to run the + // program using the current system language. In real programs, we would do + // it unconditionally for localized programs -- or never do it at all for + // the other ones. + const wxLanguageInfo* const + langInfo = wxLocale::GetLanguageInfo(wxLANGUAGE_DEFAULT); + const wxString + langDesc = langInfo ? langInfo->Description + : "the default system locale"; + + if ( m_setLocale == Locale_Ask ) { - int lng = wxGetSingleChoiceIndex - ( - _("Please choose language:"), - _("Language"), - WXSIZEOF(langNames), - langNames - ); - m_lang = lng == -1 ? wxLANGUAGE_DEFAULT : langIds[lng]; + m_setLocale = wxMessageBox + ( + wxString::Format + ( + "Would you like to use the program in %s?", + langDesc + ), + "wxWidgets i18n (internat) sample", + wxYES_NO + ) == wxYES ? Locale_Set : Locale_Skip; } - // don't use wxLOCALE_LOAD_DEFAULT flag so that Init() doesn't return - // false just because it failed to load wxstd catalog - if ( !m_locale.Init(m_lang, wxLOCALE_DONT_LOAD_DEFAULT) ) + if ( m_setLocale == Locale_Set ) { - wxLogWarning(_("This language is not supported by the system.")); + if ( !wxUILocale::UseDefault() ) + { + wxLogWarning("Failed to initialize the default system locale."); + } - // continue nevertheless - } - // normally this wouldn't be necessary as the catalog files would be found - // in the default locations, but when the program is not installed the - // catalogs are in the build directory where we wouldn't find them by - // default - wxLocale::AddCatalogLookupPathPrefix("."); + // Independently of whether we succeeded to set the locale or not, try + // to load the translations (for the default system language) here. - // Initialize the catalogs we'll be using - const wxLanguageInfo* pInfo = wxLocale::GetLanguageInfo(m_lang); - if (!m_locale.AddCatalog("internat")) - { - wxLogError(_("Couldn't find/load the 'internat' catalog for locale '%s'."), - pInfo ? pInfo->GetLocaleName() : _("unknown")); - } + // normally this wouldn't be necessary as the catalog files would be found + // in the default locations, but when the program is not installed the + // catalogs are in the build directory where we wouldn't find them by + // default + wxFileTranslationsLoader::AddCatalogLookupPathPrefix("."); - // Now try to add wxstd.mo so that loading "NOTEXIST.ING" file will produce - // a localized error message: - m_locale.AddCatalog("wxstd"); - // NOTE: it's not an error if we couldn't find it! + // Create the object for message translation and set it up for global use. + wxTranslations* const trans = new wxTranslations(); + wxTranslations::Set(trans); - // this catalog is installed in standard location on Linux systems and - // shows that you may make use of the standard message catalogs as well - // - // if it's not installed on your system, it is just silently ignored + // Initialize the catalogs we'll be using. + if ( !trans->AddCatalog("internat") ) + { + wxLogError(_("Couldn't find/load 'internat' catalog for %s."), + langDesc); + } + + // Now try to add wxstd.mo so that loading "NOTEXIST.ING" file will produce + // a localized error message: + trans->AddCatalog("wxstd"); + // NOTE: it's not an error if we couldn't find it! + + // this catalog is installed in standard location on Linux systems and + // shows that you may make use of the standard message catalogs as well + // + // if it's not installed on your system, it is just silently ignored #ifdef USE_COREUTILS_MO - wxLocale::AddCatalogLookupPathPrefix("/usr/share/locale"); - g_loadedCoreutilsMO = m_locale.AddCatalog("coreutils"); + wxFileTranslationsLoader::AddCatalogLookupPathPrefix("/usr/share/locale"); + g_loadedCoreutilsMO = trans->AddCatalog("coreutils"); #endif // USE_COREUTILS_MO + } // Create the main frame window - MyFrame *frame = new MyFrame(m_locale); + MyFrame *frame = new MyFrame(); // Show the frame frame->Show(true); @@ -297,11 +283,10 @@ bool MyApp::OnInit() // ---------------------------------------------------------------------------- // main frame constructor -MyFrame::MyFrame(wxLocale& locale) +MyFrame::MyFrame() : wxFrame(NULL, wxID_ANY, - _("International wxWidgets App")), - m_locale(locale) + _("International wxWidgets App")) { SetIcon(wxICON(sample)); @@ -316,6 +301,7 @@ MyFrame::MyFrame(wxLocale& locale) wxMenu *test_menu = new wxMenu; test_menu->Append(wxID_OPEN, _("&Open bogus file"), _("Shows a wxWidgets localized error message")); + test_menu->Append(wxID_SAVE, _("&Save dummy file"), _("Shows a localized standard dialog")); test_menu->Append(INTERNAT_PLAY, _("&Play a game"), _("A little game; hint: 17 is a lucky number for many")); test_menu->AppendSeparator(); test_menu->Append(INTERNAT_TEST_1, _("&1 _() (gettext)"), _("Tests the _() macro")); @@ -360,13 +346,79 @@ MyFrame::MyFrame(wxLocale& locale) // this demonstrates RTL support in wxStatusBar: CreateStatusBar(1); - // this demonstrates RTL layout mirroring for Arabic locales + wxPanel* const panel = new wxPanel(this); + + wxSizer* const topSizer = new wxBoxSizer(wxVERTICAL); + + // create controls showing the locale being used + topSizer->Add(new wxStaticText + ( + panel, + wxID_ANY, + wxString::Format + ( + _("Current UI locale: %s; C locale: %s"), + wxUILocale::GetCurrent().GetName(), + setlocale(LC_ALL, NULL) + ) + ), + wxSizerFlags().Center().Border()); + + // create some controls affected by the locale + + // this demonstrates RTL layout mirroring for Arabic locales and using + // locale-specific decimal separator in wxSpinCtrlDouble. wxSizer *sizer = new wxBoxSizer(wxHORIZONTAL); - sizer->Add(new wxStaticText(this, wxID_ANY, _("First")), - wxSizerFlags().Border()); - sizer->Add(new wxStaticText(this, wxID_ANY, _("Second")), - wxSizerFlags().Border()); - SetSizer(sizer); + sizer->Add(new wxStaticText(panel, wxID_ANY, _("Numeric input:")), + wxSizerFlags().Center().Border()); + + wxSpinCtrlDouble* const spin = new wxSpinCtrlDouble(panel, wxID_ANY); + spin->SetDigits(2); + spin->SetValue(12.34); + sizer->Add(spin, wxSizerFlags().Center().Border()); + + topSizer->Add(sizer, wxSizerFlags().Center()); + + // show that week days and months names are translated too + topSizer->Add(new wxCalendarCtrl(panel, wxID_ANY), + wxSizerFlags().Center().Border()); + + // another control using locale-specific number and date format + wxGrid* const grid = new wxGrid(panel, wxID_ANY, + wxDefaultPosition, wxDefaultSize, + wxBORDER_SIMPLE); + grid->CreateGrid(2, 2); + grid->HideRowLabels(); + + grid->SetColLabelValue(0, _("Number")); + grid->SetColFormatFloat(0); + grid->SetCellValue(0, 0, wxNumberFormatter::ToString(3.14159265, -1)); + + grid->SetColLabelValue(1, _("Date")); + grid->SetColFormatDate(1); + grid->SetCellValue(0, 1, "Today"); + + topSizer->Add(grid, wxSizerFlags().Center().Border()); + + // show the difference (in decimal and thousand separator, hence use a + // floating point number > 1000) between wxString::Format() and + // wxNumberFormatter: the former uses the current C locale, while the + // latter uses the UI locale + topSizer->Add(new wxStaticText + ( + panel, + wxID_ANY, + wxString::Format + ( + _("Number in UI locale: %s; in C locale: %.2f"), + wxNumberFormatter::ToString(1234567.89, 2), + 1234567.89 + ) + ), + wxSizerFlags().Center().Border()); + + panel->SetSizer(topSizer); + topSizer->SetSizeHints(this); } void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event) ) @@ -376,20 +428,10 @@ void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event) ) void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) { - wxString localeInfo; - wxString locale = m_locale.GetLocale(); - wxString sysname = m_locale.GetSysName(); - wxString canname = m_locale.GetCanonicalName(); - - localeInfo.Printf(_("Language: %s\nSystem locale name: %s\nCanonical locale name: %s\n"), - locale, sysname, canname ); - wxMessageDialog dlg( this, - wxString(_("I18n sample\n(c) 1998, 1999 Vadim Zeitlin and Julian Smart")) - + "\n\n" - + localeInfo, - _("About Internat"), + _("I18n sample\n(c) 1998, 1999 Vadim Zeitlin and Julian Smart"), + _("About Internat"), wxOK | wxICON_INFORMATION ); dlg.ShowModal(); @@ -510,6 +552,13 @@ void MyFrame::OnOpen(wxCommandEvent& WXUNUSED(event)) wxFile file("NOTEXIST.ING"); } +void MyFrame::OnSave(wxCommandEvent& WXUNUSED(event)) +{ + // show this file dialog just to check that the locale-specific elements in + // it (such as dates) follow the current locale convnetions + wxSaveFileSelector(_("Dummy file dialog"), ".ext", "dummy", this); +} + void MyFrame::OnTest1(wxCommandEvent& WXUNUSED(event)) { const wxString& title = _("Testing _() (gettext)"); diff --git a/src/common/datavcmn.cpp b/src/common/datavcmn.cpp index 7d25c8fe2b..f17b761ffa 100644 --- a/src/common/datavcmn.cpp +++ b/src/common/datavcmn.cpp @@ -28,6 +28,8 @@ #include "wx/choice.h" #include "wx/imaglist.h" #include "wx/renderer.h" +#include "wx/uilocale.h" + #if wxUSE_ACCESSIBILITY #include "wx/access.h" #endif // wxUSE_ACCESSIBILITY @@ -1999,23 +2001,28 @@ bool wxDataViewDateRenderer::GetValue(wxVariant& value) const return true; } +wxString wxDataViewDateRenderer::FormatDate() const +{ + return m_date.Format(wxGetUIDateFormat()); +} + #if wxUSE_ACCESSIBILITY wxString wxDataViewDateRenderer::GetAccessibleDescription() const { - return m_date.FormatDate(); + return FormatDate(); } #endif // wxUSE_ACCESSIBILITY bool wxDataViewDateRenderer::Render(wxRect cell, wxDC* dc, int state) { - wxString tmp = m_date.FormatDate(); + wxString tmp = FormatDate(); RenderText( tmp, 0, cell, dc, state ); return true; } wxSize wxDataViewDateRenderer::GetSize() const { - return GetTextExtent(m_date.FormatDate()); + return GetTextExtent(FormatDate()); } #endif // (defined(wxHAS_GENERIC_DATAVIEWCTRL) || defined(__WXGTK__)) && wxUSE_DATEPICKCTRL diff --git a/src/common/intl.cpp b/src/common/intl.cpp index 6dc41e4b05..5f2a74788f 100644 --- a/src/common/intl.cpp +++ b/src/common/intl.cpp @@ -43,18 +43,6 @@ #include #endif -#ifdef __WIN32__ - #include "wx/dynlib.h" - #include "wx/msw/private.h" - - #ifndef LOCALE_SNAME - #define LOCALE_SNAME 0x5c - #endif - #ifndef LOCALE_CUSTOM_UI_DEFAULT - #define LOCALE_CUSTOM_UI_DEFAULT 0x1400 - #endif -#endif - #include "wx/file.h" #include "wx/filename.h" #include "wx/tokenzr.h" @@ -63,13 +51,18 @@ #include "wx/apptrait.h" #include "wx/stdpaths.h" #include "wx/hashset.h" +#include "wx/uilocale.h" -#if defined(__WXOSX__) +#ifdef __WIN32__ + #include "wx/msw/private/uilocale.h" +#elif defined(__WXOSX__) #include "wx/osx/core/cfref.h" #include "wx/osx/core/cfstring.h" #include #include #include +#elif defined(__UNIX__) + #include "wx/unix/private/uilocale.h" #endif // ---------------------------------------------------------------------------- @@ -88,31 +81,6 @@ static wxLocale *wxSetLocale(wxLocale *pLocale); -namespace -{ - -#if defined(__UNIX__) - -// get just the language part ("en" in "en_GB") -inline wxString ExtractLang(const wxString& langFull) -{ - return langFull.BeforeFirst('_'); -} - -// get everything else (including the leading '_') -inline wxString ExtractNotLang(const wxString& langFull) -{ - size_t pos = langFull.find('_'); - if ( pos != wxString::npos ) - return langFull.substr(pos); - else - return wxString(); -} - -#endif // __UNIX__ - -} // anonymous namespace - // ---------------------------------------------------------------------------- // wxLanguageInfo // ---------------------------------------------------------------------------- @@ -396,89 +364,6 @@ bool wxLocale::DoCommonPostInit(bool success, return success; } -#if defined(__UNIX__) - -// Helper of wxSetlocaleTryAll() below which tries setting the given locale -// with and without UTF-8 suffix. Don't use this one directly. -static const char *wxSetlocaleTryUTF8(int c, const wxString& lc) -{ - const char *l = NULL; - - // NB: We prefer to set UTF-8 locale if it's possible and only fall back to - // non-UTF-8 locale if it fails, but this is not necessary under the - // supported macOS versions where xx_YY locales are just aliases to - // xx_YY.UTF-8 anyhow. -#if wxUSE_UNICODE && !defined(__WXMAC__) - if ( !lc.empty() ) - { - wxString buf(lc); - wxString buf2; - buf2 = buf + wxS(".UTF-8"); - l = wxSetlocale(c, buf2); - if ( !l ) - { - buf2 = buf + wxS(".utf-8"); - l = wxSetlocale(c, buf2); - } - if ( !l ) - { - buf2 = buf + wxS(".UTF8"); - l = wxSetlocale(c, buf2); - } - if ( !l ) - { - buf2 = buf + wxS(".utf8"); - l = wxSetlocale(c, buf2); - } - } - - // if we can't set UTF-8 locale, try non-UTF-8 one: - if ( !l ) -#endif // wxUSE_UNICODE && !__WXMAC__ - l = wxSetlocale(c, lc); - - return l; -} - -// Try setting all possible versions of the given locale, i.e. with and without -// UTF-8 encoding, and with or without the "_territory" part. -static const char *wxSetlocaleTryAll(int c, const wxString& lc) -{ - const char* l = wxSetlocaleTryUTF8(c, lc); - if ( !l ) - { - const wxString& lcOnlyLang = ExtractLang(lc); - if ( lcOnlyLang != lc ) - l = wxSetlocaleTryUTF8(c, lcOnlyLang); - } - - return l; -} - -#endif // __UNIX__ - -#ifdef __WIN32__ - -// Trivial wrapper for ::SetThreadUILanguage(). -// -// TODO-XP: Drop this when we don't support XP any longer. -static void wxMSWSetThreadUILanguage(LANGID langid) -{ - // SetThreadUILanguage() is available on XP, but with unclear - // behavior, so avoid calling it there. - if ( wxGetWinVersion() >= wxWinVersion_Vista ) - { - wxLoadedDLL dllKernel32(wxS("kernel32.dll")); - typedef LANGID(WINAPI *SetThreadUILanguage_t)(LANGID); - SetThreadUILanguage_t pfnSetThreadUILanguage = NULL; - wxDL_INIT_FUNC(pfn, SetThreadUILanguage, dllKernel32); - if (pfnSetThreadUILanguage) - pfnSetThreadUILanguage(langid); - } -} - -#endif // __WIN32__ - bool wxLocale::Init(int lang, int flags) { #if WXWIN_COMPATIBILITY_2_8 @@ -522,76 +407,19 @@ bool wxLocale::Init(int lang, int flags) #if defined(__UNIX__) || defined(__WIN32__) + bool ok = lang == wxLANGUAGE_DEFAULT ? wxUILocale::UseDefault() + : wxUILocale::UseLanguage(*info); + + // Under (non-Darwn) Unix wxUILocale already set the C locale, but under + // the other platforms we still have to do it here. +#if defined(__WIN32__) || defined(__WXOSX__) + // We prefer letting the CRT to set its locale on its own when using // default locale, as it does a better job of it than we do. We also have // to do this when we didn't recognize the default language at all. const char *retloc = lang == wxLANGUAGE_DEFAULT ? wxSetlocale(LC_ALL, "") - : NULL; + : info->TrySetLocale(); -#if defined(__UNIX__) - if ( !retloc ) - retloc = wxSetlocaleTryAll(LC_ALL, shortName); - - if ( !retloc ) - { - // Some C libraries (namely glibc) still use old ISO 639, - // so will translate the abbrev for them - wxString localeAlt; - const wxString& langOnly = ExtractLang(shortName); - if ( langOnly == wxS("he") ) - localeAlt = wxS("iw") + ExtractNotLang(shortName); - else if ( langOnly == wxS("id") ) - localeAlt = wxS("in") + ExtractNotLang(shortName); - else if ( langOnly == wxS("yi") ) - localeAlt = wxS("ji") + ExtractNotLang(shortName); - else if ( langOnly == wxS("nb") ) - localeAlt = wxS("no_NO"); - else if ( langOnly == wxS("nn") ) - localeAlt = wxS("no_NY"); - - if ( !localeAlt.empty() ) - retloc = wxSetlocaleTryAll(LC_ALL, localeAlt); - } - -#ifdef __AIX__ - // at least in AIX 5.2 libc is buggy and the string returned from - // setlocale(LC_ALL) can't be passed back to it because it returns 6 - // strings (one for each locale category), i.e. for C locale we get back - // "C C C C C C" - // - // this contradicts IBM own docs but this is not of much help, so just work - // around it in the crudest possible manner - char* p = const_cast(wxStrchr(retloc, ' ')); - if ( p ) - *p = '\0'; -#endif // __AIX__ - -#elif defined(__WIN32__) - if ( lang == wxLANGUAGE_DEFAULT ) - { - ::SetThreadLocale(LOCALE_USER_DEFAULT); - wxMSWSetThreadUILanguage(LANG_USER_DEFAULT); - - // CRT locale already set above. - } - else if ( info->WinLang == 0 ) - { - wxLogWarning(wxS("Locale '%s' not supported by OS."), name); - - retloc = "C"; - } - else // language supported by Windows - { - const wxUint32 lcid = info->GetLCID(); - - // change locale used by Windows functions - ::SetThreadLocale(lcid); - - wxMSWSetThreadUILanguage(LANGIDFROMLCID(lcid)); - - // and also call setlocale() to change locale used by the CRT - retloc = info->TrySetLocale(); - } #if wxUSE_UNICODE && (defined(__VISUALC__) || defined(__MINGW32__)) // VC++ setlocale() (also used by Mingw) can't set locale to languages that // can only be written using Unicode, therefore wxSetlocale() call fails @@ -607,13 +435,15 @@ bool wxLocale::Init(int lang, int flags) } } #endif // CRT not handling Unicode-only languages -#else - #error "Unsupported platform" -#endif + + if ( !retloc ) + ok = false; + +#endif // __WIN32__ return DoCommonPostInit ( - retloc != NULL, + ok, name, // wxLANGUAGE_DEFAULT needs to be passed to wxTranslations as "" // for correct detection of user's preferred language(s) @@ -648,9 +478,6 @@ inline bool wxGetNonEmptyEnvVar(const wxString& name, wxString* value) size_t i = 0, count = ms_languagesDB->GetCount(); -#if defined(__UNIX__) - // first get the string identifying the language from the environment - wxString langFull; #ifdef __WXOSX__ wxCFRef userLocaleRef(CFLocaleCopyCurrent()); @@ -658,10 +485,34 @@ inline bool wxGetNonEmptyEnvVar(const wxString& name, wxString* value) // az_Cyrl_AZ@calendar=buddhist;currency=JPY we just recreate the base info as expected by wx here wxCFStringRef str(wxCFRetain((CFStringRef)CFLocaleGetValue(userLocaleRef, kCFLocaleLanguageCode))); - langFull = str.AsString()+"_"; + const wxString langPrefix = str.AsString() + "_"; + str.reset(wxCFRetain((CFStringRef)CFLocaleGetValue(userLocaleRef, kCFLocaleCountryCode))); - langFull += str.AsString(); -#else + const wxString langFull = langPrefix + str.AsString(); + + int langOnlyMatchIndex = wxNOT_FOUND; + for ( i = 0; i < count; i++ ) + { + const wxString& fullname = ms_languagesDB->Item(i).CanonicalName; + if ( langFull == fullname ) + { + // Exact match, no need to look any further. + break; + } + + if ( fullname.StartsWith(langPrefix) ) + { + // Matched just the language, keep looking, but we'll keep this if + // we don't find an exact match later. + langOnlyMatchIndex = i; + } + } + + if ( i == count && langOnlyMatchIndex != wxNOT_FOUND ) + i = langOnlyMatchIndex; +#elif defined(__UNIX__) + // first get the string identifying the language from the environment + wxString langFull; if (!wxGetNonEmptyEnvVar(wxS("LC_ALL"), &langFull) && !wxGetNonEmptyEnvVar(wxS("LC_MESSAGES"), &langFull) && !wxGetNonEmptyEnvVar(wxS("LANG"), &langFull)) @@ -670,8 +521,6 @@ inline bool wxGetNonEmptyEnvVar(const wxString& name, wxString* value) return wxLANGUAGE_ENGLISH_US; } -#endif - // the language string has the following form // // lang[_LANG][.encoding][@modifier] @@ -1118,8 +967,7 @@ wxLocale::~wxLocale() } #ifdef __WIN32__ - ::SetThreadLocale(m_oldLCID); - wxMSWSetThreadUILanguage(LANGIDFROMLCID(m_oldLCID)); + wxUseLCID(m_oldLCID); #endif } @@ -1145,6 +993,13 @@ bool wxLocale::IsAvailable(int lang) if ( !::IsValidLocale(info->GetLCID(), LCID_INSTALLED) ) return false; +#elif defined(__WXOSX__) + CFLocaleRef + cfloc = CFLocaleCreate(kCFAllocatorDefault, wxCFStringRef(info->CanonicalName)); + if ( !cfloc ) + return false; + + CFRelease(cfloc); #elif defined(__UNIX__) // Test if setting the locale works, then set it back. @@ -1601,6 +1456,10 @@ wxString wxTranslateFromUnicodeFormat(const wxString& fmt) #if defined(__WINDOWS__) +// This function is also used by wxUILocaleImpl, so don't make it private. +extern wxString +wxGetInfoFromLCID(LCID lcid, wxLocaleInfo index, wxLocaleCategory cat); + namespace { @@ -1624,10 +1483,38 @@ LCTYPE GetLCTYPEFormatFromLocalInfo(wxLocaleInfo index) return 0; } +// This private function additionally checks consistency of the decimal +// separator settings between MSW and CRT. wxString -GetInfoFromLCID(LCID lcid, - wxLocaleInfo index, - wxLocaleCategory cat = wxLOCALE_CAT_DEFAULT) +GetInfoFromLCID(LCID lcid, wxLocaleInfo index, wxLocaleCategory cat) +{ + const wxString str = wxGetInfoFromLCID(lcid, index, cat); + + if ( !str.empty() && index == wxLOCALE_DECIMAL_POINT ) + { + // As we get our decimal point separator from Win32 and not the + // CRT there is a possibility of mismatch between them and this + // can easily happen if the user code called setlocale() + // instead of using wxLocale to change the locale. And this can + // result in very strange bugs elsewhere in the code as the + // assumptions that formatted strings do use the decimal + // separator actually fail, so check for it here. + wxASSERT_MSG + ( + wxString::Format("%.3f", 1.23).find(str) != wxString::npos, + "Decimal separator mismatch -- did you use setlocale()?" + "If so, use wxLocale to change the locale instead." + ); + } + + return str; +} + +} // anonymous namespace + +// This function is also used by wxUILocaleImpl, so don't make it private. +wxString +wxGetInfoFromLCID(LCID lcid, wxLocaleInfo index, wxLocaleCategory cat) { wxString str; @@ -1650,20 +1537,6 @@ GetInfoFromLCID(LCID lcid, WXSIZEOF(buf)) ) { str = buf; - - // As we get our decimal point separator from Win32 and not the - // CRT there is a possibility of mismatch between them and this - // can easily happen if the user code called setlocale() - // instead of using wxLocale to change the locale. And this can - // result in very strange bugs elsewhere in the code as the - // assumptions that formatted strings do use the decimal - // separator actually fail, so check for it here. - wxASSERT_MSG - ( - wxString::Format("%.3f", 1.23).find(str) != wxString::npos, - "Decimal separator mismatch -- did you use setlocale()?" - "If so, use wxLocale to change the locale instead." - ); } break; @@ -1686,12 +1559,12 @@ GetInfoFromLCID(LCID lcid, // alternate representation here) { const wxString - datefmt = GetInfoFromLCID(lcid, wxLOCALE_SHORT_DATE_FMT); + datefmt = wxGetInfoFromLCID(lcid, wxLOCALE_SHORT_DATE_FMT, cat); if ( datefmt.empty() ) break; const wxString - timefmt = GetInfoFromLCID(lcid, wxLOCALE_TIME_FMT); + timefmt = wxGetInfoFromLCID(lcid, wxLOCALE_TIME_FMT, cat); if ( timefmt.empty() ) break; @@ -1706,8 +1579,6 @@ GetInfoFromLCID(LCID lcid, return str; } -} // anonymous namespace - /* static */ wxString wxLocale::GetInfo(wxLocaleInfo index, wxLocaleCategory cat) { @@ -1766,34 +1637,19 @@ wxString wxLocale::GetOSInfo(wxLocaleInfo index, wxLocaleCategory cat) #elif defined(__WXOSX__) -/* static */ -wxString wxLocale::GetInfo(wxLocaleInfo index, wxLocaleCategory WXUNUSED(cat)) +// This function is also used by wxUILocaleImpl, so don't make it private. +extern wxString +wxGetInfoFromCFLocale(CFLocaleRef cfloc, wxLocaleInfo index, wxLocaleCategory WXUNUSED(cat)) { - CFLocaleRef userLocaleRefRaw; - if ( wxGetLocale() ) - { - userLocaleRefRaw = CFLocaleCreate - ( - kCFAllocatorDefault, - wxCFStringRef(wxGetLocale()->GetCanonicalName()) - ); - } - else // no current locale, use the default one - { - userLocaleRefRaw = CFLocaleCopyCurrent(); - } - - wxCFRef userLocaleRef(userLocaleRefRaw); - CFStringRef cfstr = 0; switch ( index ) { case wxLOCALE_THOUSANDS_SEP: - cfstr = (CFStringRef) CFLocaleGetValue(userLocaleRef, kCFLocaleGroupingSeparator); + cfstr = (CFStringRef) CFLocaleGetValue(cfloc, kCFLocaleGroupingSeparator); break; case wxLOCALE_DECIMAL_POINT: - cfstr = (CFStringRef) CFLocaleGetValue(userLocaleRef, kCFLocaleDecimalSeparator); + cfstr = (CFStringRef) CFLocaleGetValue(cfloc, kCFLocaleDecimalSeparator); break; case wxLOCALE_SHORT_DATE_FMT: @@ -1823,7 +1679,7 @@ wxString wxLocale::GetInfo(wxLocaleInfo index, wxLocaleCategory WXUNUSED(cat)) return wxString(); } wxCFRef dateFormatter( CFDateFormatterCreate - (NULL, userLocaleRef, dateStyle, timeStyle)); + (NULL, cfloc, dateStyle, timeStyle)); wxCFStringRef cfs = wxCFRetain( CFDateFormatterGetFormat(dateFormatter )); wxString format = wxTranslateFromUnicodeFormat(cfs.AsString()); // we always want full years @@ -1840,6 +1696,28 @@ wxString wxLocale::GetInfo(wxLocaleInfo index, wxLocaleCategory WXUNUSED(cat)) return str.AsString(); } +/* static */ +wxString wxLocale::GetInfo(wxLocaleInfo index, wxLocaleCategory cat) +{ + CFLocaleRef userLocaleRefRaw; + if ( wxGetLocale() ) + { + userLocaleRefRaw = CFLocaleCreate + ( + kCFAllocatorDefault, + wxCFStringRef(wxGetLocale()->GetCanonicalName()) + ); + } + else // no current locale, use the default one + { + userLocaleRefRaw = CFLocaleCopyCurrent(); + } + + wxCFRef userLocaleRef(userLocaleRefRaw); + + return wxGetInfoFromCFLocale(userLocaleRef, index, cat); +} + #else // !__WINDOWS__ && !__WXOSX__, assume generic POSIX namespace @@ -1935,22 +1813,34 @@ wxString wxLocale::GetInfo(wxLocaleInfo index, wxLocaleCategory cat) switch ( index ) { case wxLOCALE_THOUSANDS_SEP: - if ( cat == wxLOCALE_CAT_NUMBER ) - return lc->thousands_sep; - else if ( cat == wxLOCALE_CAT_MONEY ) - return lc->mon_thousands_sep; + switch ( cat ) + { + case wxLOCALE_CAT_DEFAULT: + case wxLOCALE_CAT_NUMBER: + return lc->thousands_sep; - wxFAIL_MSG( "invalid wxLocaleCategory" ); + case wxLOCALE_CAT_MONEY: + return lc->mon_thousands_sep; + + default: + wxFAIL_MSG( "invalid wxLocaleCategory" ); + } break; case wxLOCALE_DECIMAL_POINT: - if ( cat == wxLOCALE_CAT_NUMBER ) - return lc->decimal_point; - else if ( cat == wxLOCALE_CAT_MONEY ) - return lc->mon_decimal_point; + switch ( cat ) + { + case wxLOCALE_CAT_DEFAULT: + case wxLOCALE_CAT_NUMBER: + return lc->decimal_point; - wxFAIL_MSG( "invalid wxLocaleCategory" ); + case wxLOCALE_CAT_MONEY: + return lc->mon_decimal_point; + + default: + wxFAIL_MSG( "invalid wxLocaleCategory" ); + } break; case wxLOCALE_SHORT_DATE_FMT: diff --git a/src/common/numformatter.cpp b/src/common/numformatter.cpp index e57ab02335..c59ea520db 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); @@ -217,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. @@ -330,5 +285,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); } diff --git a/src/common/uilocale.cpp b/src/common/uilocale.cpp new file mode 100644 index 0000000000..4843f823e5 --- /dev/null +++ b/src/common/uilocale.cpp @@ -0,0 +1,102 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: src/common/uilocale.cpp +// Purpose: wxUILocale implementation +// Author: Vadim Zeitlin +// Created: 2021-07-31 +// Copyright: (c) 2021 Vadim Zeitlin +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +// for compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#if wxUSE_INTL + +#include "wx/uilocale.h" + +#include "wx/private/uilocale.h" + +// ---------------------------------------------------------------------------- +// global variables +// ---------------------------------------------------------------------------- + +// This static global variable doesn't need to be protected from concurrent +// access as it's only supposed to be used from the UI thread. +/* static */ +wxUILocale wxUILocale::ms_current; + +// ============================================================================ +// implementation +// ============================================================================ + +/* static */ +bool wxUILocale::UseDefault() +{ + // We don't attempt to optimize this function by checking whether + // ms_current is already set to the user default locale, as we're + // supposed to be called just once during the program lifetime anyhow. + + wxUILocaleImpl* const impl = wxUILocaleImpl::CreateUserDefault(); + if ( !impl ) + return false; + + ms_current.SetImpl(impl); + + return true; +} + +/* static */ +bool wxUILocale::UseLanguage(const wxLanguageInfo& info) +{ + wxUILocaleImpl* const impl = wxUILocaleImpl::CreateForLanguage(info); + if ( !impl ) + return false; + + ms_current.SetImpl(impl); + + return true; +} + +/* static */ +const wxUILocale& wxUILocale::GetCurrent() +{ + // We initialize it on demand. + if ( !ms_current.m_impl ) + { + ms_current.SetImpl(wxUILocaleImpl::CreateStdC()); + } + + return ms_current; +} + +void wxUILocale::SetImpl(wxUILocaleImpl* impl) +{ + delete m_impl; + + m_impl = impl; +} + +wxString wxUILocale::GetName() const +{ + return m_impl->GetName(); +} + +wxString wxUILocale::GetInfo(wxLocaleInfo index, wxLocaleCategory cat) const +{ + return m_impl->GetInfo(index, cat); +} + +wxUILocale::~wxUILocale() +{ + delete m_impl; +} + +#endif // wxUSE_INTL diff --git a/src/generic/gridctrl.cpp b/src/generic/gridctrl.cpp index 8ba3582b2c..4c526f81b5 100644 --- a/src/generic/gridctrl.cpp +++ b/src/generic/gridctrl.cpp @@ -25,8 +25,10 @@ #include "wx/checkbox.h" #endif // WX_PRECOMP +#include "wx/numformatter.h" #include "wx/tokenzr.h" #include "wx/renderer.h" +#include "wx/uilocale.h" #include "wx/generic/private/grid.h" #include "wx/private/window.h" @@ -159,7 +161,7 @@ wxGridCellDateRenderer::wxGridCellDateRenderer(const wxString& outformat) { if ( outformat.empty() ) { - m_oformat = "%x"; // Localized date representation. + m_oformat = wxGetUIDateFormat(); } else { @@ -839,7 +841,7 @@ wxString wxGridCellFloatRenderer::GetString(const wxGrid& grid, int row, int col else { text = table->GetValue(row, col); - hasDouble = text.ToDouble(&val); + hasDouble = wxNumberFormatter::FromString(text, &val); } if ( hasDouble ) @@ -877,8 +879,7 @@ wxString wxGridCellFloatRenderer::GetString(const wxGrid& grid, int row, int col m_format += wxT('f'); } - text.Printf(m_format, val); - + text = wxNumberFormatter::Format(m_format, val); } //else: text already contains the string diff --git a/src/generic/grideditors.cpp b/src/generic/grideditors.cpp index 6cdce725eb..96832ee9de 100644 --- a/src/generic/grideditors.cpp +++ b/src/generic/grideditors.cpp @@ -29,12 +29,14 @@ #include "wx/listbox.h" #endif +#include "wx/numformatter.h" #include "wx/valnum.h" #include "wx/textfile.h" #include "wx/spinctrl.h" #include "wx/tokenzr.h" #include "wx/renderer.h" #include "wx/datectrl.h" +#include "wx/uilocale.h" #include "wx/generic/gridsel.h" #include "wx/generic/grideditors.h" @@ -997,7 +999,7 @@ void wxGridCellFloatEditor::BeginEdit(int row, int col, wxGrid* grid) const wxString value = table->GetValue(row, col); if ( !value.empty() ) { - if ( !value.ToDouble(&m_value) ) + if ( !wxNumberFormatter::FromString(value, &m_value) ) { wxFAIL_MSG( wxT("this cell doesn't have float value") ); return; @@ -1018,7 +1020,7 @@ bool wxGridCellFloatEditor::EndEdit(int WXUNUSED(row), double value; if ( !text.empty() ) { - if ( !text.ToDouble(&value) ) + if ( !wxNumberFormatter::FromString(text, &value) ) return false; } else // new value is empty string @@ -1060,20 +1062,9 @@ void wxGridCellFloatEditor::Reset() void wxGridCellFloatEditor::StartingKey(wxKeyEvent& event) { int keycode = event.GetKeyCode(); - char tmpbuf[2]; - tmpbuf[0] = (char) keycode; - tmpbuf[1] = '\0'; - wxString strbuf(tmpbuf, *wxConvCurrent); - -#if wxUSE_INTL - bool is_decimal_point = ( strbuf == - wxLocale::GetInfo(wxLOCALE_DECIMAL_POINT, wxLOCALE_CAT_NUMBER) ); -#else - bool is_decimal_point = ( strbuf == wxT(".") ); -#endif if ( wxIsdigit(keycode) || keycode == '+' || keycode == '-' - || is_decimal_point ) + || keycode == wxNumberFormatter::GetDecimalSeparator() ) { wxGridCellTextEditor::StartingKey(event); @@ -1197,7 +1188,7 @@ wxString wxGridCellFloatEditor::GetString() m_format += wxT('f'); } - return wxString::Format(m_format, m_value); + return wxNumberFormatter::Format(m_format, m_value); } bool wxGridCellFloatEditor::IsAcceptedKey(wxKeyEvent& event) @@ -1207,17 +1198,10 @@ bool wxGridCellFloatEditor::IsAcceptedKey(wxKeyEvent& event) const int keycode = event.GetKeyCode(); if ( wxIsascii(keycode) ) { -#if wxUSE_INTL - const wxString decimalPoint = - wxLocale::GetInfo(wxLOCALE_DECIMAL_POINT, wxLOCALE_CAT_NUMBER); -#else - const wxString decimalPoint(wxT('.')); -#endif - // accept digits, 'e' as in '1e+6', also '-', '+', and '.' if ( wxIsdigit(keycode) || tolower(keycode) == 'e' || - keycode == decimalPoint || + keycode == wxNumberFormatter::GetDecimalSeparator() || keycode == '+' || keycode == '-' ) { @@ -1869,7 +1853,7 @@ wxGridCellDateEditor::wxGridCellDateEditor(const wxString& format) void wxGridCellDateEditor::SetParameters(const wxString& params) { if ( params.empty() ) - m_format = "%x"; + m_format = wxGetUIDateFormat(); else m_format = params; } diff --git a/src/generic/spinctlg.cpp b/src/generic/spinctlg.cpp index 7e87d1937a..0dc60a9102 100644 --- a/src/generic/spinctlg.cpp +++ b/src/generic/spinctlg.cpp @@ -41,6 +41,7 @@ wxIMPLEMENT_DYNAMIC_CLASS(wxSpinDoubleEvent, wxNotifyEvent); #if wxUSE_SPINBTN +#include "wx/numformatter.h" #include "wx/valnum.h" #include "wx/valtext.h" @@ -764,12 +765,12 @@ void wxSpinCtrlDouble::DoSendEvent() bool wxSpinCtrlDouble::DoTextToValue(const wxString& text, double *val) { - return text.ToDouble(val); + return wxNumberFormatter::FromString(text, val); } wxString wxSpinCtrlDouble::DoValueToText(double val) { - return wxString::Format(m_format, val); + return wxNumberFormatter::ToString(val, m_digits); } void wxSpinCtrlDouble::SetIncrement(double inc) @@ -812,8 +813,6 @@ void wxSpinCtrlDouble::DoSetDigitsAndUpdate(unsigned digits) void wxSpinCtrlDouble::DoSetDigits(unsigned digits) { m_digits = digits; - - m_format.Printf(wxT("%%0.%ulf"), digits); } void wxSpinCtrlDouble::ResetTextValidator() diff --git a/src/msw/uilocale.cpp b/src/msw/uilocale.cpp new file mode 100644 index 0000000000..6916fefe52 --- /dev/null +++ b/src/msw/uilocale.cpp @@ -0,0 +1,141 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: src/msw/uilocale.cpp +// Purpose: wxUILocale implementation for MSW +// Author: Vadim Zeitlin +// Created: 2021-07-31 +// Copyright: (c) 2021 Vadim Zeitlin +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +// for compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#if wxUSE_INTL + +#include "wx/private/uilocale.h" + +#include "wx/msw/private/uilocale.h" + +#include "wx/dynlib.h" + +// ============================================================================ +// implementation +// ============================================================================ + +// ---------------------------------------------------------------------------- +// helper functions +// ---------------------------------------------------------------------------- + +namespace +{ + +// Trivial wrapper for ::SetThreadUILanguage(). +// +// TODO-XP: Drop this when we don't support XP any longer. +static void wxMSWSetThreadUILanguage(LANGID langid) +{ + // SetThreadUILanguage() is available on XP, but with unclear + // behavior, so avoid calling it there. + if ( wxGetWinVersion() >= wxWinVersion_Vista ) + { + wxLoadedDLL dllKernel32(wxS("kernel32.dll")); + typedef LANGID(WINAPI *SetThreadUILanguage_t)(LANGID); + SetThreadUILanguage_t pfnSetThreadUILanguage = NULL; + wxDL_INIT_FUNC(pfn, SetThreadUILanguage, dllKernel32); + if (pfnSetThreadUILanguage) + pfnSetThreadUILanguage(langid); + } +} + +} // anonymous namespace + +void wxUseLCID(LCID lcid) +{ + ::SetThreadLocale(lcid); + + wxMSWSetThreadUILanguage(LANGIDFROMLCID(lcid)); +} + +// ---------------------------------------------------------------------------- +// wxUILocale implementation for MSW +// ---------------------------------------------------------------------------- + +// TODO-XP: Replace this with an implementation using GetLocaleInfoEx() when we +// don't support XP any longer. +class wxUILocaleImplLCID : public wxUILocaleImpl +{ +public: + explicit wxUILocaleImplLCID(LCID lcid) + : m_lcid(lcid) + { + wxUseLCID(lcid); + } + + wxString GetName() const wxOVERRIDE + { + wxChar buf[256]; + buf[0] = wxT('\0'); + + // Try using newer constant available since Vista which produces names + // more similar to the other platforms. + if ( wxGetWinVersion() >= wxWinVersion_Vista ) + { + ::GetLocaleInfo(m_lcid, LOCALE_SNAME, buf, WXSIZEOF(buf)); + } + else // TODO-XP: Drop this branch. + { + // This name constant is available under all systems, including + // pre-Vista ones. + ::GetLocaleInfo(m_lcid, LOCALE_SENGLANGUAGE, buf, WXSIZEOF(buf)); + } + + return buf; + } + + wxString GetInfo(wxLocaleInfo index, wxLocaleCategory cat) const wxOVERRIDE + { + return wxGetInfoFromLCID(m_lcid, index, cat); + } + +private: + const LCID m_lcid; + + wxDECLARE_NO_COPY_CLASS(wxUILocaleImplLCID); +}; + +/* static */ +wxUILocaleImpl* wxUILocaleImpl::CreateStdC() +{ + // There is no LCID for "C" locale, but US English is basically the same. + LCID lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT); + return new wxUILocaleImplLCID(lcid); +} + +/* static */ +wxUILocaleImpl* wxUILocaleImpl::CreateUserDefault() +{ + return new wxUILocaleImplLCID(LOCALE_USER_DEFAULT); +} + +/* static */ +wxUILocaleImpl* wxUILocaleImpl::CreateForLanguage(const wxLanguageInfo& info) +{ + if ( info.WinLang == 0 ) + { + wxLogWarning(wxS("Locale '%s' not supported by OS."), info.Description); + + return NULL; + } + + return new wxUILocaleImplLCID(info.GetLCID()); +} + +#endif // wxUSE_INTL diff --git a/src/osx/core/uilocale.cpp b/src/osx/core/uilocale.cpp new file mode 100644 index 0000000000..96a0058f5a --- /dev/null +++ b/src/osx/core/uilocale.cpp @@ -0,0 +1,103 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: src/osx/core/uilocale.cpp +// Purpose: wxUILocale implementation for macOS +// Author: Vadim Zeitlin +// Created: 2021-08-01 +// Copyright: (c) 2021 Vadim Zeitlin +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +// for compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#if wxUSE_INTL + +#include "wx/private/uilocale.h" + +#include "wx/osx/core/cfref.h" +#include "wx/osx/core/cfstring.h" + +#include +#include + +extern wxString +wxGetInfoFromCFLocale(CFLocaleRef cfloc, wxLocaleInfo index, wxLocaleCategory cat); + +namespace +{ + +// ---------------------------------------------------------------------------- +// wxUILocale implementation using Core Foundation +// ---------------------------------------------------------------------------- + +class wxUILocaleImplCF : public wxUILocaleImpl +{ +public: + explicit wxUILocaleImplCF(const wxCFRef& cfloc) + : m_cfloc(cfloc) + { + } + + static wxUILocaleImplCF* Create(const wxString& name) + { + CFLocaleRef cfloc = CFLocaleCreate(kCFAllocatorDefault, wxCFStringRef(name)); + if ( !cfloc ) + return NULL; + + return new wxUILocaleImplCF(cfloc); + } + + wxString GetName() const wxOVERRIDE; + wxString GetInfo(wxLocaleInfo index, wxLocaleCategory cat) const wxOVERRIDE; + +private: + wxCFRef m_cfloc; + + wxDECLARE_NO_COPY_CLASS(wxUILocaleImplCF); +}; + +} // anonymous namespace + +// ============================================================================ +// implementation +// ============================================================================ + +wxString +wxUILocaleImplCF::GetName() const +{ + return wxCFStringRef::AsString(CFLocaleGetIdentifier(m_cfloc)); +} + +wxString +wxUILocaleImplCF::GetInfo(wxLocaleInfo index, wxLocaleCategory cat) const +{ + return wxGetInfoFromCFLocale(m_cfloc, index, cat); +} + +/* static */ +wxUILocaleImpl* wxUILocaleImpl::CreateStdC() +{ + return wxUILocaleImplCF::Create("C"); +} + +/* static */ +wxUILocaleImpl* wxUILocaleImpl::CreateUserDefault() +{ + return new wxUILocaleImplCF(CFLocaleCopyCurrent()); +} + +/* static */ +wxUILocaleImpl* wxUILocaleImpl::CreateForLanguage(const wxLanguageInfo& info) +{ + return wxUILocaleImplCF::Create(info.CanonicalName); +} + +#endif // wxUSE_INTL diff --git a/src/unix/uilocale.cpp b/src/unix/uilocale.cpp new file mode 100644 index 0000000000..f4b86fa0a0 --- /dev/null +++ b/src/unix/uilocale.cpp @@ -0,0 +1,186 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: src/unix/uilocale.cpp +// Purpose: wxUILocale implementation for Unix systems +// Author: Vadim Zeitlin +// Created: 2021-08-01 +// Copyright: (c) 2021 Vadim Zeitlin +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +// for compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#if wxUSE_INTL + +#include "wx/private/uilocale.h" + +#include "wx/unix/private/uilocale.h" + +#include "wx/intl.h" + +#include + +namespace +{ + +// ---------------------------------------------------------------------------- +// wxUILocale implementation using standard Unix/C functions +// ---------------------------------------------------------------------------- + +class wxUILocaleImplUnix : public wxUILocaleImpl +{ +public: + // Locale argument may be NULL to not change it at all. + explicit wxUILocaleImplUnix(const char* locale); + + wxString GetName() const wxOVERRIDE; + wxString GetInfo(wxLocaleInfo index, wxLocaleCategory cat) const wxOVERRIDE; + +private: + wxDECLARE_NO_COPY_CLASS(wxUILocaleImplUnix); +}; + +} // anonymous namespace + +// ============================================================================ +// implementation +// ============================================================================ + +// Helper of wxSetlocaleTryAll() below which tries setting the given locale +// with and without UTF-8 suffix. Don't use this one directly. +static const char *wxSetlocaleTryUTF8(int c, const wxString& lc) +{ + const char *l = NULL; + + // NB: We prefer to set UTF-8 locale if it's possible and only fall back to + // non-UTF-8 locale if it fails, but this is not necessary under the + // supported macOS versions where xx_YY locales are just aliases to + // xx_YY.UTF-8 anyhow. +#if wxUSE_UNICODE && !defined(__WXMAC__) + if ( !lc.empty() ) + { + wxString buf(lc); + wxString buf2; + buf2 = buf + wxS(".UTF-8"); + l = wxSetlocale(c, buf2); + if ( !l ) + { + buf2 = buf + wxS(".utf-8"); + l = wxSetlocale(c, buf2); + } + if ( !l ) + { + buf2 = buf + wxS(".UTF8"); + l = wxSetlocale(c, buf2); + } + if ( !l ) + { + buf2 = buf + wxS(".utf8"); + l = wxSetlocale(c, buf2); + } + } + + // if we can't set UTF-8 locale, try non-UTF-8 one: + if ( !l ) +#endif // wxUSE_UNICODE && !__WXMAC__ + l = wxSetlocale(c, lc); + + return l; +} + +// Try setting all possible versions of the given locale, i.e. with and without +// UTF-8 encoding, and with or without the "_territory" part. +const char *wxSetlocaleTryAll(int c, const wxString& lc) +{ + const char* l = wxSetlocaleTryUTF8(c, lc); + if ( !l ) + { + const wxString& lcOnlyLang = ExtractLang(lc); + if ( lcOnlyLang != lc ) + l = wxSetlocaleTryUTF8(c, lcOnlyLang); + } + + return l; +} + +// ---------------------------------------------------------------------------- +// wxUILocale implementation for Unix +// ---------------------------------------------------------------------------- + +wxUILocaleImplUnix::wxUILocaleImplUnix(const char* locale) +{ + if ( locale ) + setlocale(LC_ALL, locale); +} + +wxString +wxUILocaleImplUnix::GetName() const +{ + return wxString::FromAscii(setlocale(LC_ALL, NULL)); +} + +wxString +wxUILocaleImplUnix::GetInfo(wxLocaleInfo index, wxLocaleCategory cat) const +{ + // Currently we rely on the user code not calling setlocale() itself, so + // that the current locale is still the same as was set in the ctor. + // + // If this assumption turns out to be wrong, we could use wxLocaleSetter to + // temporarily change the locale here (maybe only if setlocale(NULL) result + // differs from the expected one). + return wxLocale::GetInfo(index, cat); +} + +/* static */ +wxUILocaleImpl* wxUILocaleImpl::CreateStdC() +{ + return new wxUILocaleImplUnix(NULL); +} + +/* static */ +wxUILocaleImpl* wxUILocaleImpl::CreateUserDefault() +{ + return new wxUILocaleImplUnix(""); +} + +/* static */ +wxUILocaleImpl* wxUILocaleImpl::CreateForLanguage(const wxLanguageInfo& info) +{ + // Set the locale before creating the wxUILocaleImplUnix object in order to + // check if we succeed in doing it. + + const wxString& shortName = info.CanonicalName; + + if ( !wxSetlocaleTryAll(LC_ALL, shortName) ) + { + // Some C libraries (namely glibc) still use old ISO 639, + // so will translate the abbrev for them + wxString localeAlt; + const wxString& langOnly = ExtractLang(shortName); + if ( langOnly == wxS("he") ) + localeAlt = wxS("iw") + ExtractNotLang(shortName); + else if ( langOnly == wxS("id") ) + localeAlt = wxS("in") + ExtractNotLang(shortName); + else if ( langOnly == wxS("yi") ) + localeAlt = wxS("ji") + ExtractNotLang(shortName); + else if ( langOnly == wxS("nb") ) + localeAlt = wxS("no_NO"); + else if ( langOnly == wxS("nn") ) + localeAlt = wxS("no_NY"); + + if ( localeAlt.empty() || !wxSetlocaleTryAll(LC_ALL, localeAlt) ) + return NULL; + } + + return new wxUILocaleImplUnix(NULL); +} + +#endif // wxUSE_INTL diff --git a/tests/controls/textctrltest.cpp b/tests/controls/textctrltest.cpp index 5bf21bff22..a5283f3fce 100644 --- a/tests/controls/textctrltest.cpp +++ b/tests/controls/textctrltest.cpp @@ -33,6 +33,8 @@ #include "wx/stopwatch.h" #endif +#include "wx/private/localeset.h" + #include "textentrytest.h" #include "testableframe.h" #include "asserthelper.h" @@ -295,7 +297,7 @@ void TextCtrlTestCase::StreamInput() #ifndef __WXOSX__ { // Ensure we use decimal point and not a comma. - LocaleSetter setCLocale("C"); + wxCLocaleSetter setCLocale; *m_text << "stringinput" << 10 diff --git a/tests/datetime/datetimetest.cpp b/tests/datetime/datetimetest.cpp index 8ecf70f2c6..0a03babc54 100644 --- a/tests/datetime/datetimetest.cpp +++ b/tests/datetime/datetimetest.cpp @@ -22,6 +22,8 @@ #include "wx/wxcrt.h" // for wxStrstr() +#include "wx/private/localeset.h" + // to test Today() meaningfully we must be able to change the system date which // is not usually the case, but if we're under Win32 we can try it -- define // the macro below to do it @@ -1304,7 +1306,7 @@ void DateTimeTestCase::TestDateTimeParse() // the test strings here use "PM" which is not available in all locales so // we need to use "C" locale for them - CLocaleSetter cloc; + wxCLocaleSetter cloc; wxDateTime dt; for ( size_t n = 0; n < WXSIZEOF(parseTestDates); n++ ) diff --git a/tests/filename/filenametest.cpp b/tests/filename/filenametest.cpp index a650deff7e..3134bbe53d 100644 --- a/tests/filename/filenametest.cpp +++ b/tests/filename/filenametest.cpp @@ -22,6 +22,8 @@ #include "wx/stdpaths.h" #include "wx/scopeguard.h" +#include "wx/private/localeset.h" + #ifdef __WINDOWS__ #include "wx/msw/registry.h" #include "wx/msw/wrapshl.h" @@ -493,7 +495,7 @@ TEST_CASE("wxFileName::GetHumanReadable", "[filename]") { "304 KB", 304351, 0, wxSIZE_CONV_SI }, }; - CLocaleSetter loc; // we want to use "C" locale for LC_NUMERIC + wxCLocaleSetter loc; // we want to use "C" locale for LC_NUMERIC // so that regardless of the system's locale // the decimal point used by GetHumanReadableSize() // is always '.' diff --git a/tests/intl/intltest.cpp b/tests/intl/intltest.cpp index c19628b4c0..d6db0c8a56 100644 --- a/tests/intl/intltest.cpp +++ b/tests/intl/intltest.cpp @@ -18,6 +18,7 @@ #endif // WX_PRECOMP #include "wx/intl.h" +#include "wx/uilocale.h" #if wxUSE_INTL @@ -239,4 +240,17 @@ TEST_CASE("wxLocale::Default", "[locale]") #endif // wxUSE_UNICODE +// This test doesn't run by default as it only works in locales using decimal +// point as separator, which doesn't need to be the case. +TEST_CASE("wxUILocale::GetInfo", "[.][uilocale]") +{ + REQUIRE( wxUILocale::UseDefault() ); + + const wxUILocale& loc = wxUILocale::GetCurrent(); + + WARN( "Using locale " << loc.GetName() ); + + CHECK( loc.GetInfo(wxLOCALE_DECIMAL_POINT) == "." ); +} + #endif // wxUSE_INTL diff --git a/tests/mbconv/mbconvtest.cpp b/tests/mbconv/mbconvtest.cpp index 8306759fb0..53309c4b60 100644 --- a/tests/mbconv/mbconvtest.cpp +++ b/tests/mbconv/mbconvtest.cpp @@ -22,6 +22,8 @@ #include "wx/txtstrm.h" #include "wx/mstream.h" +#include "wx/private/localeset.h" + #if defined wxHAVE_TCHAR_SUPPORT && !defined HAVE_WCHAR_H #define HAVE_WCHAR_H #endif @@ -1106,7 +1108,7 @@ void MBConvTestCase::LibcTests() // supposed to use the same CRT -- no idea why and unfortunately gdb is too // flaky to debug it) #ifdef __VISUALC__ - LocaleSetter loc("English_United States.1252"); + wxLocaleSetter loc("English_United States.1252"); wxMBConvLibc convLibc; TestCoder( diff --git a/tests/strings/vsnprintf.cpp b/tests/strings/vsnprintf.cpp index 53f48c3e2e..f1fa10f99f 100644 --- a/tests/strings/vsnprintf.cpp +++ b/tests/strings/vsnprintf.cpp @@ -24,6 +24,7 @@ #include "wx/wxchar.h" #endif // WX_PRECOMP +#include "wx/private/localeset.h" // NOTE: for more info about the specification of wxVsnprintf() behaviour you can // refer to the following page of the GNU libc manual: @@ -85,10 +86,10 @@ wxUnsafeSnprintf(T *buf, size_t len, const wxChar *fmt, ...) // Explicitly set C locale to avoid check failures when running on machines // with a locale where the decimal point is not '.' -class VsnprintfTestCase : CLocaleSetter +class VsnprintfTestCase : wxCLocaleSetter { public: - VsnprintfTestCase() : CLocaleSetter() { } + VsnprintfTestCase() : wxCLocaleSetter() { } protected: template diff --git a/tests/testprec.h b/tests/testprec.h index 1dcaa0a289..ef38886526 100644 --- a/tests/testprec.h +++ b/tests/testprec.h @@ -148,38 +148,6 @@ extern bool IsAutomaticTest(); extern bool IsRunningUnderXVFB(); -// Helper class setting the locale to the given one for its lifetime. -class LocaleSetter -{ -public: - LocaleSetter(const char *loc) - : m_locOld(wxStrdupA(setlocale(LC_ALL, NULL))) - { - setlocale(LC_ALL, loc); - } - - ~LocaleSetter() - { - setlocale(LC_ALL, m_locOld); - free(m_locOld); - } - -private: - char * const m_locOld; - - wxDECLARE_NO_COPY_CLASS(LocaleSetter); -}; - -// An even simpler helper for setting the locale to "C" one during its lifetime. -class CLocaleSetter : private LocaleSetter -{ -public: - CLocaleSetter() : LocaleSetter("C") { } - -private: - wxDECLARE_NO_COPY_CLASS(CLocaleSetter); -}; - #if wxUSE_GUI // Return true if the UI tests are enabled, used by WXUISIM_TEST().