]> git.saurik.com Git - wxWidgets.git/blame_incremental - include/wx/translation.h
wxMessageBox off the main thread lost result code.
[wxWidgets.git] / include / wx / translation.h
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: wx/translation.h
3// Purpose: Internationalization and localisation for wxWidgets
4// Author: Vadim Zeitlin, Vaclav Slavik,
5// Michael N. Filippov <michael@idisys.iae.nsk.su>
6// Created: 2010-04-23
7// Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
8// (c) 2010 Vaclav Slavik <vslavik@fastmail.fm>
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#ifndef _WX_TRANSLATION_H_
13#define _WX_TRANSLATION_H_
14
15#include "wx/defs.h"
16#include "wx/string.h"
17
18#if wxUSE_INTL
19
20#include "wx/buffer.h"
21#include "wx/language.h"
22#include "wx/hashmap.h"
23#include "wx/strconv.h"
24#include "wx/scopedptr.h"
25
26// ============================================================================
27// global decls
28// ============================================================================
29
30// ----------------------------------------------------------------------------
31// macros
32// ----------------------------------------------------------------------------
33
34// gettext() style macros (notice that xgettext should be invoked with
35// --keyword="_" --keyword="wxPLURAL:1,2" options
36// to extract the strings from the sources)
37#ifndef WXINTL_NO_GETTEXT_MACRO
38 #define _(s) wxGetTranslation((s))
39 #define wxPLURAL(sing, plur, n) wxGetTranslation((sing), (plur), n)
40#endif
41
42// another one which just marks the strings for extraction, but doesn't
43// perform the translation (use -kwxTRANSLATE with xgettext!)
44#define wxTRANSLATE(str) str
45
46// ----------------------------------------------------------------------------
47// forward decls
48// ----------------------------------------------------------------------------
49
50class WXDLLIMPEXP_FWD_BASE wxArrayString;
51class WXDLLIMPEXP_FWD_BASE wxTranslationsLoader;
52class WXDLLIMPEXP_FWD_BASE wxLocale;
53
54class wxPluralFormsCalculator;
55wxDECLARE_SCOPED_PTR(wxPluralFormsCalculator, wxPluralFormsCalculatorPtr)
56
57// ----------------------------------------------------------------------------
58// wxMsgCatalog corresponds to one loaded message catalog.
59// ----------------------------------------------------------------------------
60
61class WXDLLIMPEXP_BASE wxMsgCatalog
62{
63public:
64 // Ctor is protected, because CreateFromXXX functions must be used,
65 // but destruction should be unrestricted
66#if !wxUSE_UNICODE
67 ~wxMsgCatalog();
68#endif
69
70 // load the catalog from disk or from data; caller is responsible for
71 // deleting them if not NULL
72 static wxMsgCatalog *CreateFromFile(const wxString& filename,
73 const wxString& domain);
74
75 static wxMsgCatalog *CreateFromData(const wxScopedCharBuffer& data,
76 const wxString& domain);
77
78 // get name of the catalog
79 wxString GetDomain() const { return m_domain; }
80
81 // get the translated string: returns NULL if not found
82 const wxString *GetString(const wxString& sz, unsigned n = UINT_MAX) const;
83
84protected:
85 wxMsgCatalog(const wxString& domain)
86 : m_pNext(NULL), m_domain(domain)
87#if !wxUSE_UNICODE
88 , m_conv(NULL)
89#endif
90 {}
91
92private:
93 // variable pointing to the next element in a linked list (or NULL)
94 wxMsgCatalog *m_pNext;
95 friend class wxTranslations;
96
97 wxStringToStringHashMap m_messages; // all messages in the catalog
98 wxString m_domain; // name of the domain
99
100#if !wxUSE_UNICODE
101 // the conversion corresponding to this catalog charset if we installed it
102 // as the global one
103 wxCSConv *m_conv;
104#endif
105
106 wxPluralFormsCalculatorPtr m_pluralFormsCalculator;
107};
108
109// ----------------------------------------------------------------------------
110// wxTranslations: message catalogs
111// ----------------------------------------------------------------------------
112
113// this class allows to get translations for strings
114class WXDLLIMPEXP_BASE wxTranslations
115{
116public:
117 wxTranslations();
118 ~wxTranslations();
119
120 // returns current translations object, may return NULL
121 static wxTranslations *Get();
122 // sets current translations object (takes ownership; may be NULL)
123 static void Set(wxTranslations *t);
124
125 // changes loader to non-default one; takes ownership of 'loader'
126 void SetLoader(wxTranslationsLoader *loader);
127
128 void SetLanguage(wxLanguage lang);
129 void SetLanguage(const wxString& lang);
130
131 // get languages available for this app
132 wxArrayString GetAvailableTranslations(const wxString& domain) const;
133
134 // find best translation language for given domain
135 wxString GetBestTranslation(const wxString& domain, wxLanguage msgIdLanguage);
136 wxString GetBestTranslation(const wxString& domain,
137 const wxString& msgIdLanguage = "en");
138
139 // add standard wxWidgets catalog ("wxstd")
140 bool AddStdCatalog();
141
142 // add catalog with given domain name and language, looking it up via
143 // wxTranslationsLoader
144 bool AddCatalog(const wxString& domain);
145 bool AddCatalog(const wxString& domain, wxLanguage msgIdLanguage);
146#if !wxUSE_UNICODE
147 bool AddCatalog(const wxString& domain,
148 wxLanguage msgIdLanguage,
149 const wxString& msgIdCharset);
150#endif
151
152 // check if the given catalog is loaded
153 bool IsLoaded(const wxString& domain) const;
154
155 // access to translations
156 const wxString *GetTranslatedString(const wxString& origString,
157 const wxString& domain = wxEmptyString) const;
158 const wxString *GetTranslatedString(const wxString& origString,
159 unsigned n,
160 const wxString& domain = wxEmptyString) const;
161
162 wxString GetHeaderValue(const wxString& header,
163 const wxString& domain = wxEmptyString) const;
164
165 // this is hack to work around a problem with wxGetTranslation() which
166 // returns const wxString& and not wxString, so when it returns untranslated
167 // string, it needs to have a copy of it somewhere
168 static const wxString& GetUntranslatedString(const wxString& str);
169
170private:
171 // perform loading of the catalog via m_loader
172 bool LoadCatalog(const wxString& domain, const wxString& lang, const wxString& msgIdLang);
173
174 // find catalog by name in a linked list, return NULL if !found
175 wxMsgCatalog *FindCatalog(const wxString& domain) const;
176
177 // same as Set(), without taking ownership; only for wxLocale
178 static void SetNonOwned(wxTranslations *t);
179 friend class wxLocale;
180
181private:
182 wxString m_lang;
183 wxTranslationsLoader *m_loader;
184
185 wxMsgCatalog *m_pMsgCat; // pointer to linked list of catalogs
186};
187
188
189// abstraction of translations discovery and loading
190class WXDLLIMPEXP_BASE wxTranslationsLoader
191{
192public:
193 wxTranslationsLoader() {}
194 virtual ~wxTranslationsLoader() {}
195
196 virtual wxMsgCatalog *LoadCatalog(const wxString& domain,
197 const wxString& lang) = 0;
198
199 virtual wxArrayString GetAvailableTranslations(const wxString& domain) const = 0;
200};
201
202
203// standard wxTranslationsLoader implementation, using filesystem
204class WXDLLIMPEXP_BASE wxFileTranslationsLoader
205 : public wxTranslationsLoader
206{
207public:
208 static void AddCatalogLookupPathPrefix(const wxString& prefix);
209
210 virtual wxMsgCatalog *LoadCatalog(const wxString& domain,
211 const wxString& lang);
212
213 virtual wxArrayString GetAvailableTranslations(const wxString& domain) const;
214};
215
216
217#ifdef __WINDOWS__
218// loads translations from win32 resources
219class WXDLLIMPEXP_BASE wxResourceTranslationsLoader
220 : public wxTranslationsLoader
221{
222public:
223 virtual wxMsgCatalog *LoadCatalog(const wxString& domain,
224 const wxString& lang);
225
226 virtual wxArrayString GetAvailableTranslations(const wxString& domain) const;
227
228protected:
229 // returns resource type to use for translations
230 virtual wxString GetResourceType() const { return "MOFILE"; }
231
232 // returns module to load resources from
233 virtual WXHINSTANCE GetModule() const { return 0; }
234};
235#endif // __WINDOWS__
236
237
238// ----------------------------------------------------------------------------
239// global functions
240// ----------------------------------------------------------------------------
241
242// get the translation of the string in the current locale
243inline const wxString& wxGetTranslation(const wxString& str,
244 const wxString& domain = wxString())
245{
246 wxTranslations *trans = wxTranslations::Get();
247 const wxString *transStr = trans ? trans->GetTranslatedString(str, domain)
248 : NULL;
249 if ( transStr )
250 return *transStr;
251 else
252 // NB: this function returns reference to a string, so we have to keep
253 // a copy of it somewhere
254 return wxTranslations::GetUntranslatedString(str);
255}
256
257inline const wxString& wxGetTranslation(const wxString& str1,
258 const wxString& str2,
259 unsigned n,
260 const wxString& domain = wxString())
261{
262 wxTranslations *trans = wxTranslations::Get();
263 const wxString *transStr = trans ? trans->GetTranslatedString(str1, n, domain)
264 : NULL;
265 if ( transStr )
266 return *transStr;
267 else
268 // NB: this function returns reference to a string, so we have to keep
269 // a copy of it somewhere
270 return n == 1
271 ? wxTranslations::GetUntranslatedString(str1)
272 : wxTranslations::GetUntranslatedString(str2);
273}
274
275#else // !wxUSE_INTL
276
277// the macros should still be defined - otherwise compilation would fail
278
279#if !defined(WXINTL_NO_GETTEXT_MACRO)
280 #if !defined(_)
281 #define _(s) (s)
282 #endif
283 #define wxPLURAL(sing, plur, n) ((n) == 1 ? (sing) : (plur))
284#endif
285
286#define wxTRANSLATE(str) str
287
288// NB: we use a template here in order to avoid using
289// wxLocale::GetUntranslatedString() above, which would be required if
290// we returned const wxString&; this way, the compiler should be able to
291// optimize wxGetTranslation() away
292
293template<typename TString>
294inline TString wxGetTranslation(TString str)
295 { return str; }
296
297template<typename TString, typename TDomain>
298inline TString wxGetTranslation(TString str, TDomain WXUNUSED(domain))
299 { return str; }
300
301template<typename TString, typename TDomain>
302inline TString wxGetTranslation(TString str1, TString str2, size_t n)
303 { return n == 1 ? str1 : str2; }
304
305template<typename TString, typename TDomain>
306inline TString wxGetTranslation(TString str1, TString str2, size_t n,
307 TDomain WXUNUSED(domain))
308 { return n == 1 ? str1 : str2; }
309
310#endif // wxUSE_INTL/!wxUSE_INTL
311
312// define this one just in case it occurs somewhere (instead of preferred
313// wxTRANSLATE) too
314#if !defined(WXINTL_NO_GETTEXT_MACRO)
315 #if !defined(gettext_noop)
316 #define gettext_noop(str) (str)
317 #endif
318 #if !defined(N_)
319 #define N_(s) (s)
320 #endif
321#endif
322
323#endif // _WX_TRANSLATION_H_