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>
8 // Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // (c) 2010 Vaclav Slavik <vslavik@fastmail.fm>
10 // Licence: wxWindows licence
11 /////////////////////////////////////////////////////////////////////////////
13 #ifndef _WX_TRANSLATION_H_
14 #define _WX_TRANSLATION_H_
17 #include "wx/string.h"
21 #include "wx/buffer.h"
22 #include "wx/language.h"
23 #include "wx/hashmap.h"
24 #include "wx/strconv.h"
25 #include "wx/scopedptr.h"
27 // ============================================================================
29 // ============================================================================
31 // ----------------------------------------------------------------------------
33 // ----------------------------------------------------------------------------
35 // gettext() style macros (notice that xgettext should be invoked with
36 // --keyword="_" --keyword="wxPLURAL:1,2" options
37 // to extract the strings from the sources)
38 #ifndef WXINTL_NO_GETTEXT_MACRO
39 #define _(s) wxGetTranslation((s))
40 #define wxPLURAL(sing, plur, n) wxGetTranslation((sing), (plur), n)
43 // another one which just marks the strings for extraction, but doesn't
44 // perform the translation (use -kwxTRANSLATE with xgettext!)
45 #define wxTRANSLATE(str) str
47 // ----------------------------------------------------------------------------
49 // ----------------------------------------------------------------------------
51 class WXDLLIMPEXP_FWD_BASE wxTranslationsLoader
;
52 class WXDLLIMPEXP_FWD_BASE wxLocale
;
54 class wxPluralFormsCalculator
;
55 wxDECLARE_SCOPED_PTR(wxPluralFormsCalculator
, wxPluralFormsCalculatorPtr
)
57 // ----------------------------------------------------------------------------
58 // wxMsgCatalog corresponds to one loaded message catalog.
59 // ----------------------------------------------------------------------------
61 class WXDLLIMPEXP_BASE wxMsgCatalog
64 // load the catalog from disk or from data; caller is responsible for
65 // deleting them if not NULL
66 static wxMsgCatalog
*CreateFromFile(const wxString
& filename
,
67 const wxString
& domain
);
69 static wxMsgCatalog
*CreateFromData(const wxScopedCharBuffer
& data
,
70 const wxString
& domain
);
72 // get name of the catalog
73 wxString
GetDomain() const { return m_domain
; }
75 // get the translated string: returns NULL if not found
76 const wxString
*GetString(const wxString
& sz
, unsigned n
= UINT_MAX
) const;
79 wxMsgCatalog(const wxString
& domain
)
80 : m_pNext(NULL
), m_domain(domain
)
90 // variable pointing to the next element in a linked list (or NULL)
91 wxMsgCatalog
*m_pNext
;
92 friend class wxTranslations
;
94 wxStringToStringHashMap m_messages
; // all messages in the catalog
95 wxString m_domain
; // name of the domain
98 // the conversion corresponding to this catalog charset if we installed it
103 wxPluralFormsCalculatorPtr m_pluralFormsCalculator
;
106 // ----------------------------------------------------------------------------
107 // wxTranslations: message catalogs
108 // ----------------------------------------------------------------------------
110 // this class allows to get translations for strings
111 class WXDLLIMPEXP_BASE wxTranslations
117 // returns current translations object, may return NULL
118 static wxTranslations
*Get();
119 // sets current translations object (takes ownership; may be NULL)
120 static void Set(wxTranslations
*t
);
122 // changes loader to non-default one; takes ownership of 'loader'
123 void SetLoader(wxTranslationsLoader
*loader
);
125 void SetLanguage(wxLanguage lang
);
126 void SetLanguage(const wxString
& lang
);
128 // add standard wxWidgets catalog ("wxstd")
129 bool AddStdCatalog();
131 // add catalog with given domain name and language, looking it up via
132 // wxTranslationsLoader
133 bool AddCatalog(const wxString
& domain
);
134 bool AddCatalog(const wxString
& domain
, wxLanguage msgIdLanguage
);
136 bool AddCatalog(const wxString
& domain
,
137 wxLanguage msgIdLanguage
,
138 const wxString
& msgIdCharset
);
141 // check if the given catalog is loaded
142 bool IsLoaded(const wxString
& domain
) const;
144 // access to translations
145 const wxString
& GetString(const wxString
& origString
,
146 const wxString
& domain
= wxEmptyString
) const;
147 const wxString
& GetString(const wxString
& origString
,
148 const wxString
& origString2
,
150 const wxString
& domain
= wxEmptyString
) const;
152 wxString
GetHeaderValue(const wxString
& header
,
153 const wxString
& domain
= wxEmptyString
) const;
155 // this is hack to work around a problem with wxGetTranslation() which
156 // returns const wxString& and not wxString, so when it returns untranslated
157 // string, it needs to have a copy of it somewhere
158 static const wxString
& GetUntranslatedString(const wxString
& str
);
161 // perform loading of the catalog via m_loader
162 bool LoadCatalog(const wxString
& domain
, const wxString
& lang
);
164 // find best translation for given domain
165 wxString
ChooseLanguageForDomain(const wxString
& domain
,
166 const wxString
& msgIdLang
);
168 // find catalog by name in a linked list, return NULL if !found
169 wxMsgCatalog
*FindCatalog(const wxString
& domain
) const;
171 // same as Set(), without taking ownership; only for wxLocale
172 static void SetNonOwned(wxTranslations
*t
);
173 friend class wxLocale
;
177 wxTranslationsLoader
*m_loader
;
179 wxMsgCatalog
*m_pMsgCat
; // pointer to linked list of catalogs
183 // abstraction of translations discovery and loading
184 class WXDLLIMPEXP_BASE wxTranslationsLoader
187 wxTranslationsLoader() {}
188 virtual ~wxTranslationsLoader() {}
190 virtual wxMsgCatalog
*LoadCatalog(const wxString
& domain
,
191 const wxString
& lang
) = 0;
195 // standard wxTranslationsLoader implementation, using filesystem
196 class WXDLLIMPEXP_BASE wxFileTranslationsLoader
197 : public wxTranslationsLoader
200 static void AddCatalogLookupPathPrefix(const wxString
& prefix
);
202 virtual wxMsgCatalog
*LoadCatalog(const wxString
& domain
,
203 const wxString
& lang
);
208 // loads translations from win32 resources
209 class WXDLLIMPEXP_BASE wxResourceTranslationsLoader
210 : public wxTranslationsLoader
213 virtual wxMsgCatalog
*LoadCatalog(const wxString
& domain
,
214 const wxString
& lang
);
217 // returns resource type to use for translations
218 virtual wxString
GetResourceType() const { return "MOFILE"; }
220 // returns module to load resources from
221 virtual WXHINSTANCE
GetModule() const { return 0; }
223 #endif // __WINDOWS__
226 // ----------------------------------------------------------------------------
228 // ----------------------------------------------------------------------------
230 // get the translation of the string in the current locale
231 inline const wxString
& wxGetTranslation(const wxString
& str
,
232 const wxString
& domain
= wxEmptyString
)
234 wxTranslations
*trans
= wxTranslations
::Get();
236 return trans
->GetString(str
, domain
);
238 // NB: this function returns reference to a string, so we have to keep
239 // a copy of it somewhere
240 return wxTranslations
::GetUntranslatedString(str
);
243 inline const wxString
& wxGetTranslation(const wxString
& str1
,
244 const wxString
& str2
,
246 const wxString
& domain
= wxEmptyString
)
248 wxTranslations
*trans
= wxTranslations
::Get();
250 return trans
->GetString(str1
, str2
, n
, domain
);
252 // NB: this function returns reference to a string, so we have to keep
253 // a copy of it somewhere
255 ? wxTranslations
::GetUntranslatedString(str1
)
256 : wxTranslations
::GetUntranslatedString(str2
);
261 // the macros should still be defined - otherwise compilation would fail
263 #if !defined(WXINTL_NO_GETTEXT_MACRO)
267 #define wxPLURAL(sing, plur, n) ((n) == 1 ? (sing) : (plur))
270 #define wxTRANSLATE(str) str
272 // NB: we use a template here in order to avoid using
273 // wxLocale::GetUntranslatedString() above, which would be required if
274 // we returned const wxString&; this way, the compiler should be able to
275 // optimize wxGetTranslation() away
277 template<typename TString
>
278 inline TString
wxGetTranslation(TString str
)
281 template<typename TString
, typename TDomain
>
282 inline TString
wxGetTranslation(TString str
, TDomain
WXUNUSED(domain
))
285 template<typename TString
, typename TDomain
>
286 inline TString
wxGetTranslation(TString str1
, TString str2
, size_t n
)
287 { return n
== 1 ? str1
: str2
; }
289 template<typename TString
, typename TDomain
>
290 inline TString
wxGetTranslation(TString str1
, TString str2
, size_t n
,
291 TDomain
WXUNUSED(domain
))
292 { return n
== 1 ? str1
: str2
; }
294 #endif // wxUSE_INTL/!wxUSE_INTL
296 // define this one just in case it occurs somewhere (instead of preferred
298 #if !defined(WXINTL_NO_GETTEXT_MACRO)
299 #if !defined(gettext_noop)
300 #define gettext_noop(str) (str)
307 #endif // _WX_TRANSLATION_H_