]> git.saurik.com Git - wxWidgets.git/blame - src/common/xlocale.cpp
Update all windows associated with the tooltip when it changes in wxMSW.
[wxWidgets.git] / src / common / xlocale.cpp
CommitLineData
6e4ae332
VZ
1//////////////////////////////////////////////////////////////////////////////
2// Name: src/common/xlocale.cpp
3// Purpose: xlocale wrappers/impl to provide some xlocale wrappers
4// Author: Brian Vanderburg II, Vadim Zeitlin
5// Created: 2008-01-07
6// RCS-ID: $Id$
7// Copyright: (c) 2008 Brian Vanderburg II
8// 2008 Vadim Zeitlin <vadim@wxwidgets.org>
9// Licence: wxWindows licence
10///////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20#include "wx/wxprec.h"
21
22#ifdef __BORLANDC__
23 #pragma hdrstop
24#endif
25
26#if wxUSE_XLOCALE
27
28#ifndef WX_PRECOMP
29 #include "wx/module.h"
30#endif
31
32#include "wx/xlocale.h"
33
28e0798f 34#include <errno.h>
c71498a1 35#include <locale.h>
28e0798f 36
6e4ae332
VZ
37// ----------------------------------------------------------------------------
38// module globals
39// ----------------------------------------------------------------------------
40
41// This is the C locale object, it is created on demand
42static wxXLocale *gs_cLocale = NULL;
43
dad013ac
FM
44wxXLocale wxNullXLocale;
45
46
6e4ae332
VZ
47// ============================================================================
48// implementation
49// ============================================================================
50
51// ----------------------------------------------------------------------------
52// Module for gs_cLocale cleanup
53// ----------------------------------------------------------------------------
54
55class wxXLocaleModule : public wxModule
56{
57public:
58 virtual bool OnInit() { return true; }
59 virtual void OnExit() { wxDELETE(gs_cLocale); }
60
61 DECLARE_DYNAMIC_CLASS(wxXLocaleModule)
62};
63
64IMPLEMENT_DYNAMIC_CLASS(wxXLocaleModule, wxModule)
65
66
67// ============================================================================
68// wxXLocale implementation
69// ============================================================================
70
71// ----------------------------------------------------------------------------
72// common parts
73// ----------------------------------------------------------------------------
74
75// Get the C locale
76wxXLocale& wxXLocale::GetCLocale()
77{
78 if ( !gs_cLocale )
79 {
5c33522f 80 gs_cLocale = new wxXLocale(static_cast<wxXLocaleCTag *>(NULL));
6e4ae332
VZ
81 }
82
83 return *gs_cLocale;
84}
85
45f5fbd4
VZ
86#ifdef wxHAS_XLOCALE_SUPPORT
87
6e4ae332
VZ
88wxXLocale::wxXLocale(wxLanguage lang)
89{
90 const wxLanguageInfo * const info = wxLocale::GetLanguageInfo(lang);
91 if ( !info )
92 {
93 m_locale = NULL;
94 }
95 else
96 {
e340b786 97 Init(info->GetLocaleName().c_str());
6e4ae332
VZ
98 }
99}
100
6e4ae332
VZ
101#if wxCHECK_VISUALC_VERSION(8)
102
103// ----------------------------------------------------------------------------
104// implementation using MSVC locale API
105// ----------------------------------------------------------------------------
106
107void wxXLocale::Init(const char *loc)
108{
dad013ac
FM
109 if (!loc || *loc == '\0')
110 return;
111
6e4ae332
VZ
112 m_locale = _create_locale(LC_ALL, loc);
113}
114
115void wxXLocale::Free()
116{
117 if ( m_locale )
118 _free_locale(m_locale);
119}
120
121#elif defined(HAVE_LOCALE_T)
122
123// ----------------------------------------------------------------------------
124// implementation using xlocale API
125// ----------------------------------------------------------------------------
126
127void wxXLocale::Init(const char *loc)
128{
dad013ac
FM
129 if (!loc || *loc == '\0')
130 return;
131
6e4ae332 132 m_locale = newlocale(LC_ALL_MASK, loc, NULL);
dad013ac
FM
133 if (!m_locale)
134 {
135 // NOTE: here we do something similar to what wxSetLocaleTryUTF8() does
136 // in wxLocale code (but with newlocale() calls instead of wxSetlocale())
137 wxString buf(loc);
138 wxString buf2;
139 buf2 = buf + wxS(".UTF-8");
5337ab1b 140 m_locale = newlocale(LC_ALL_MASK, buf2.c_str(), NULL);
dad013ac
FM
141 if ( !m_locale )
142 {
143 buf2 = buf + wxS(".utf-8");
5337ab1b 144 m_locale = newlocale(LC_ALL_MASK, buf2.c_str(), NULL);
dad013ac
FM
145 }
146 if ( !m_locale )
147 {
148 buf2 = buf + wxS(".UTF8");
5337ab1b 149 m_locale = newlocale(LC_ALL_MASK, buf2.c_str(), NULL);
dad013ac
FM
150 }
151 if ( !m_locale )
152 {
153 buf2 = buf + wxS(".utf8");
5337ab1b 154 m_locale = newlocale(LC_ALL_MASK, buf2.c_str(), NULL);
dad013ac
FM
155 }
156 }
03647350 157
dad013ac
FM
158 // TODO: wxLocale performs many more manipulations of the given locale
159 // string in the attempt to set a valid locale; reusing that code
160 // (changing it to take a generic wxTryLocale callback) would be nice
6e4ae332
VZ
161}
162
163void wxXLocale::Free()
164{
165 if ( m_locale )
166 freelocale(m_locale);
167}
168
169#else
170 #error "Unknown xlocale support."
171#endif
172
173#endif // wxHAS_XLOCALE_SUPPORT
174
175#ifndef wxHAS_XLOCALE_SUPPORT
176
177// ============================================================================
178// Implementation of wxFoo_l() functions for "C" locale without xlocale support
179// ============================================================================
180
181// ----------------------------------------------------------------------------
182// character classification and transformation functions
183// ----------------------------------------------------------------------------
184
185// lookup table and macros for character type functions
186#define CTYPE_ALNUM 0x0001
187#define CTYPE_ALPHA 0x0002
188#define CTYPE_CNTRL 0x0004
189#define CTYPE_DIGIT 0x0008
190#define CTYPE_GRAPH 0x0010
191#define CTYPE_LOWER 0x0020
192#define CTYPE_PRINT 0x0040
193#define CTYPE_PUNCT 0x0080
194#define CTYPE_SPACE 0x0100
195#define CTYPE_UPPER 0x0200
196#define CTYPE_XDIGIT 0x0400
197
a243da29 198static const unsigned int gs_lookup[] =
6e4ae332
VZ
199{
200 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
201 0x0004, 0x0104, 0x0104, 0x0104, 0x0104, 0x0104, 0x0004, 0x0004,
202 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
203 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
204 0x0140, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0,
205 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0,
206 0x0459, 0x0459, 0x0459, 0x0459, 0x0459, 0x0459, 0x0459, 0x0459,
207 0x0459, 0x0459, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0,
208 0x00D0, 0x0653, 0x0653, 0x0653, 0x0653, 0x0653, 0x0653, 0x0253,
209 0x0253, 0x0253, 0x0253, 0x0253, 0x0253, 0x0253, 0x0253, 0x0253,
210 0x0253, 0x0253, 0x0253, 0x0253, 0x0253, 0x0253, 0x0253, 0x0253,
211 0x0253, 0x0253, 0x0253, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0,
212 0x00D0, 0x0473, 0x0473, 0x0473, 0x0473, 0x0473, 0x0473, 0x0073,
213 0x0073, 0x0073, 0x0073, 0x0073, 0x0073, 0x0073, 0x0073, 0x0073,
214 0x0073, 0x0073, 0x0073, 0x0073, 0x0073, 0x0073, 0x0073, 0x0073,
215 0x0073, 0x0073, 0x0073, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x0004
216};
217
218
219#define CTYPE_TEST(c, t) ( (c) <= 127 && (gs_lookup[(c)] & (t)) )
220
221
222// ctype functions
223#define GEN_ISFUNC(name, test) \
224int name(const wxUniChar& c, const wxXLocale& loc) \
225{ \
226 wxCHECK(loc.IsOk(), false); \
227 return CTYPE_TEST(c.GetValue(), test); \
228}
229
230GEN_ISFUNC(wxIsalnum_l, CTYPE_ALNUM)
231GEN_ISFUNC(wxIsalpha_l, CTYPE_ALPHA)
232GEN_ISFUNC(wxIscntrl_l, CTYPE_CNTRL)
233GEN_ISFUNC(wxIsdigit_l, CTYPE_DIGIT)
234GEN_ISFUNC(wxIsgraph_l, CTYPE_GRAPH)
235GEN_ISFUNC(wxIslower_l, CTYPE_LOWER)
236GEN_ISFUNC(wxIsprint_l, CTYPE_PRINT)
237GEN_ISFUNC(wxIspunct_l, CTYPE_PUNCT)
238GEN_ISFUNC(wxIsspace_l, CTYPE_SPACE)
239GEN_ISFUNC(wxIsupper_l, CTYPE_UPPER)
240GEN_ISFUNC(wxIsxdigit_l, CTYPE_XDIGIT)
241
a4e53d46 242int wxTolower_l(const wxUniChar& c, const wxXLocale& loc)
6e4ae332
VZ
243{
244 wxCHECK(loc.IsOk(), false);
245
45f5fbd4 246 if(CTYPE_TEST(c.GetValue(), CTYPE_UPPER))
6e4ae332
VZ
247 {
248 return c - 'A' + 'a';
249 }
250
251 return c;
252}
253
a4e53d46 254int wxToupper_l(const wxUniChar& c, const wxXLocale& loc)
6e4ae332
VZ
255{
256 wxCHECK(loc.IsOk(), false);
257
45f5fbd4 258 if(CTYPE_TEST(c.GetValue(), CTYPE_LOWER))
6e4ae332
VZ
259 {
260 return c - 'a' + 'A';
261 }
262
263 return c;
264}
265
28e0798f
FM
266
267// ----------------------------------------------------------------------------
268// string --> number conversion functions
269// ----------------------------------------------------------------------------
270
271/*
272 WARNING: the implementation of the wxStrtoX_l() functions below is unsafe
273 in a multi-threaded environment as we temporary change the locale
274 and if in the meanwhile an other thread performs some locale-dependent
275 operation, it may get unexpected results...
276 However this is the best we can do without reinventing the wheel in the
277 case !wxHAS_XLOCALE_SUPPORT...
278*/
279
797a2706
FM
280/*
281 Note that this code is similar to (a portion of) wxLocale::IsAvailable code
282*/
28e0798f
FM
283#define IMPLEMENT_STRTOX_L_START \
284 wxCHECK(loc.IsOk(), 0); \
285 \
375330ac
FM
286 /* (Try to) temporary set the 'C' locale */ \
287 const char *oldLocale = wxSetlocale(LC_NUMERIC, "C"); \
288 if ( !oldLocale ) \
28e0798f 289 { \
375330ac
FM
290 /* the current locale was not changed; no need to */ \
291 /* restore the previous one... */ \
28e0798f
FM
292 errno = EINVAL; \
293 /* signal an error (better than nothing) */ \
294 return 0; \
797a2706 295 }
28e0798f
FM
296
297#define IMPLEMENT_STRTOX_L_END \
298 /* restore the original locale */ \
299 wxSetlocale(LC_NUMERIC, oldLocale); \
300 return ret;
301
302double wxStrtod_l(const wchar_t* str, wchar_t **endptr, const wxXLocale& loc)
303{
304 IMPLEMENT_STRTOX_L_START
305 double ret = wxStrtod(str, endptr);
306 IMPLEMENT_STRTOX_L_END
307}
308
309double wxStrtod_l(const char* str, char **endptr, const wxXLocale& loc)
310{
311 IMPLEMENT_STRTOX_L_START
312 double ret = wxStrtod(str, endptr);
313 IMPLEMENT_STRTOX_L_END
314}
315
316long wxStrtol_l(const wchar_t* str, wchar_t **endptr, int base, const wxXLocale& loc)
03647350 317{
28e0798f
FM
318 IMPLEMENT_STRTOX_L_START
319 long ret = wxStrtol(str, endptr, base);
320 IMPLEMENT_STRTOX_L_END
321}
322
323long wxStrtol_l(const char* str, char **endptr, int base, const wxXLocale& loc)
324{
325 IMPLEMENT_STRTOX_L_START
326 long ret = wxStrtol(str, endptr, base);
327 IMPLEMENT_STRTOX_L_END
328}
329
330unsigned long wxStrtoul_l(const wchar_t* str, wchar_t **endptr, int base, const wxXLocale& loc)
331{
332 IMPLEMENT_STRTOX_L_START
333 unsigned long ret = wxStrtoul(str, endptr, base);
334 IMPLEMENT_STRTOX_L_END
335}
336
337unsigned long wxStrtoul_l(const char* str, char **endptr, int base, const wxXLocale& loc)
338{
339 IMPLEMENT_STRTOX_L_START
340 unsigned long ret = wxStrtoul(str, endptr, base);
341 IMPLEMENT_STRTOX_L_END
342}
343
344
6e4ae332
VZ
345#endif // !defined(wxHAS_XLOCALE_SUPPORT)
346
347#endif // wxUSE_XLOCALE