xref: /haiku/headers/os/locale/Catalog.h (revision c9ad965c81b08802fed0827fd1dd16f45297928a)
1 /*
2  * Copyright 2003-2009, Haiku, Inc.
3  * Distributed under the terms of the MIT License.
4  */
5 #ifndef _CATALOG_H_
6 #define _CATALOG_H_
7 
8 #include <SupportDefs.h>
9 #include <String.h>
10 
11 class BCatalogAddOn;
12 class BLocale;
13 class BMessage;
14 struct entry_ref;
15 
16 
17 class BCatalog {
18 
19 	public:
20 		BCatalog();
21 		BCatalog(const char *signature, const char *language = NULL,
22 			uint32 fingerprint = 0);
23 		virtual ~BCatalog();
24 
25 		const char *GetString(const char *string, const char *context = NULL,
26 						const char *comment = NULL);
27 		const char *GetString(uint32 id);
28 
29 		status_t GetData(const char *name, BMessage *msg);
30 		status_t GetData(uint32 id, BMessage *msg);
31 
32 		status_t GetSignature(BString *sig);
33 		status_t GetLanguage(BString *lang);
34 		status_t GetFingerprint(uint32 *fp);
35 
36 		status_t InitCheck() const;
37 		int32 CountItems() const;
38 
39 		BCatalogAddOn *CatalogAddOn();
40 
41 	protected:
42 		BCatalog(const BCatalog&);
43 		const BCatalog& operator= (const BCatalog&);
44 			// hide assignment and copy-constructor
45 
46 		static status_t GetAppCatalog(BCatalog*);
47 
48 		BCatalogAddOn *fCatalog;
49 
50 	private:
51 		friend class BLocale;
52 		friend status_t get_add_on_catalog(BCatalog*, const char *);
53 };
54 
55 
56 extern BCatalog* be_catalog;
57 extern BCatalog* be_app_catalog;
58 
59 
60 #ifndef B_AVOID_TRANSLATION_MACROS
61 // macros for easy catalog-access, define B_AVOID_TRANSLATION_MACROS if
62 // you don't want these:
63 
64 #undef TR_CONTEXT
65 	// In a single application, several strings (e.g. 'Ok') will be used
66 	// more than once, in different contexts.
67 	// As the application programmer can not know if all translations of
68 	// this string will be the same for all languages, each occurrence of
69 	// the string must be translated on its own.
70 	// Specifying the context explicitly with each string allows the person
71 	// translating a catalog to separate these different occurrences of the
72 	// same string and tell which strings appears in what context of the
73 	// application.
74 	// In order to give the translator a useful hint, the application
75 	// programmer needs to define TR_CONTEXT with the context he'd like
76 	// to be associated with the strings used in this specifc source file.
77 	// example:
78 	//		#define TR_CONTEXT "Folder-Window"
79 	// Tip: Use a descriptive name of the class implemented in that
80 	//		source-file.
81 
82 
83 // Translation macros which may be used to shorten translation requests:
84 #undef TR
85 #define TR(str) \
86 	be_catalog->GetString((str), TR_CONTEXT)
87 
88 #undef TR_CMT
89 #define TR_CMT(str, cmt) \
90 	be_catalog->GetString((str), TR_CONTEXT, (cmt))
91 
92 #undef TR_ALL
93 #define TR_ALL(str, ctx, cmt) \
94 	be_catalog->GetString((str), (ctx), (cmt))
95 
96 #undef TR_ID
97 #define TR_ID(id) \
98 	be_catalog->GetString((id))
99 
100 
101 // Translation markers which can be used to mark static strings/IDs which
102 // are used as key for translation requests (at other places in the code):
103 /* example:
104 		#define TR_CONTEXT "MyDecentApp-Menu"
105 
106 		static const char *choices[] = {
107 			TR_MARK("left"),
108 			TR_MARK("right"),
109 			TR_MARK("up"),
110 			TR_MARK("down")
111 		};
112 
113 		void MyClass::AddChoices(BMenu *menu) {
114 			for (char **ch = choices; *ch; ch++) {
115 				menu->AddItem(
116 					new BMenuItem(
117 						TR(*ch),
118 						new BMessage(...)
119 					)
120 				)
121 			}
122 		}
123 */
124 #undef TR_MARK
125 #define TR_MARK(str) \
126 	BCatalogAddOn::MarkForTranslation((str), TR_CONTEXT, "")
127 
128 #undef TR_MARK_CMT
129 #define TR_MARK_CMT(str, cmt) \
130 	BCatalogAddOn::MarkForTranslation((str), TR_CONTEXT, (cmt))
131 
132 #undef TR_MARK_ALL
133 #define TR_MARK_ALL(str, ctx, cmt) \
134 	BCatalogAddOn::MarkForTranslation((str), (ctx), (cmt))
135 
136 #undef TR_MARK_ID
137 #define TR_MARK_ID(id) \
138 	BCatalogAddOn::MarkForTranslation((id))
139 
140 #endif	/* B_AVOID_TRANSLATION_MACROS */
141 
142 
143 /************************************************************************/
144 // For BCatalog add-on implementations:
145 
146 class BCatalogAddOn {
147 		friend class BLocaleRoster;
148 	public:
149 		BCatalogAddOn(const char *signature, const char *language,
150 			uint32 fingerprint);
151 		virtual ~BCatalogAddOn();
152 
153 		virtual const char *GetString(const char *string,
154 								const char *context = NULL,
155 								const char *comment = NULL) = 0;
156 		virtual const char *GetString(uint32 id) = 0;
157 
158 		status_t InitCheck() const;
159 		BCatalogAddOn *Next();
160 
161 		// the following could be used to localize non-textual data (e.g.
162 		// icons), but these will only be implemented if there's demand for such
163 		// a feature:
164 		virtual bool CanHaveData() const;
165 		virtual status_t GetData(const char *name, BMessage *msg);
166 		virtual status_t GetData(uint32 id, BMessage *msg);
167 
168 		// interface for catalog-editor-app and testing apps:
169 		virtual status_t SetString(const char *string,
170 							const char *translated,
171 							const char *context = NULL,
172 							const char *comment = NULL);
173 		virtual status_t SetString(int32 id, const char *translated);
174 
175 		virtual bool CanWriteData() const;
176 		virtual status_t SetData(const char *name, BMessage *msg);
177 		virtual status_t SetData(uint32 id, BMessage *msg);
178 
179 		virtual status_t ReadFromFile(const char *path = NULL);
180 		virtual status_t ReadFromAttribute(entry_ref *appOrAddOnRef);
181 		virtual status_t ReadFromResource(entry_ref *appOrAddOnRef);
182 		virtual status_t WriteToFile(const char *path = NULL);
183 		virtual status_t WriteToAttribute(entry_ref *appOrAddOnRef);
184 		virtual status_t WriteToResource(entry_ref *appOrAddOnRef);
185 
186 		virtual void MakeEmpty();
187 		virtual int32 CountItems() const;
188 
189 		// magic marker functions which are used to mark a string/id
190 		// which will be translated elsewhere in the code (where it can
191 		// not be found since it is references by a variable):
192 		static const char *MarkForTranslation(const char *str, const char *ctx,
193 								const char *cmt);
194 		static int32 MarkForTranslation(int32 id);
195 
196 	protected:
197 		virtual void UpdateFingerprint();
198 
199 		status_t 			fInitCheck;
200 		BString 			fSignature;
201 		BString 			fLanguageName;
202 		uint32				fFingerprint;
203 		BCatalogAddOn 		*fNext;
204 
205 		friend class BCatalog;
206 		friend status_t get_add_on_catalog(BCatalog*, const char *);
207 };
208 
209 // every catalog-add-on should export these symbols...
210 // ...the function that instantiates a catalog for this add-on-type...
211 extern "C"
212 BCatalogAddOn *instantiate_catalog(const char *signature,
213 	const char *language, uint32 fingerprint);
214 // ...the function that creates an empty catalog for this add-on-type...
215 extern "C"
216 BCatalogAddOn *create_catalog(const char *signature,
217 	const char *language);
218 // ...and the priority which will be used to order the catalog-add-ons:
219 extern uint8 gCatalogAddOnPriority;
220 
221 
222 /*
223  * BCatalog - inlines for trivial accessors:
224  */
225 inline status_t
226 BCatalog::GetSignature(BString *sig)
227 {
228 	if (!sig)
229 		return B_BAD_VALUE;
230 	if (!fCatalog)
231 		return B_NO_INIT;
232 	*sig = fCatalog->fSignature;
233 	return B_OK;
234 }
235 
236 
237 inline status_t
238 BCatalog::GetLanguage(BString *lang)
239 {
240 	if (!lang)
241 		return B_BAD_VALUE;
242 	if (!fCatalog)
243 		return B_NO_INIT;
244 	*lang = fCatalog->fLanguageName;
245 	return B_OK;
246 }
247 
248 
249 inline status_t
250 BCatalog::GetFingerprint(uint32 *fp)
251 {
252 	if (!fp)
253 		return B_BAD_VALUE;
254 	if (!fCatalog)
255 		return B_NO_INIT;
256 	*fp = fCatalog->fFingerprint;
257 	return B_OK;
258 }
259 
260 
261 inline status_t
262 BCatalog::InitCheck() const
263 {
264 	return fCatalog
265 				? fCatalog->InitCheck()
266 				: B_NO_INIT;
267 }
268 
269 
270 inline int32
271 BCatalog::CountItems() const
272 {
273 	if (!fCatalog)
274 		return 0;
275 	return fCatalog->CountItems();
276 }
277 
278 
279 inline BCatalogAddOn *
280 BCatalog::CatalogAddOn()
281 {
282 	return fCatalog;
283 }
284 
285 
286 /*
287  * BCatalogAddOn - inlines for trivial accessors:
288  */
289 inline BCatalogAddOn *
290 BCatalogAddOn::Next()
291 {
292 	return fNext;
293 }
294 
295 
296 inline const char *
297 BCatalogAddOn::MarkForTranslation(const char *str, const char *ctx,
298 	const char *cmt)
299 {
300 	return str;
301 }
302 
303 
304 inline int32
305 BCatalogAddOn::MarkForTranslation(int32 id)
306 {
307 	return id;
308 }
309 
310 
311 namespace BPrivate {
312 
313 /*
314  * EditableCatalog
315  */
316 class EditableCatalog : public BCatalog {
317 
318 	public:
319 		EditableCatalog(const char *type, const char *signature,
320 			const char *language);
321 		~EditableCatalog();
322 
323 		status_t SetString(const char *string,
324 					const char *translated,
325 					const char *context = NULL,
326 					const char *comment = NULL);
327 		status_t SetString(int32 id, const char *translated);
328 
329 		bool CanWriteData() const;
330 		status_t SetData(const char *name, BMessage *msg);
331 		status_t SetData(uint32 id, BMessage *msg);
332 
333 		status_t ReadFromFile(const char *path = NULL);
334 		status_t ReadFromAttribute(entry_ref *appOrAddOnRef);
335 		status_t ReadFromResource(entry_ref *appOrAddOnRef);
336 		status_t WriteToFile(const char *path = NULL);
337 		status_t WriteToAttribute(entry_ref *appOrAddOnRef);
338 		status_t WriteToResource(entry_ref *appOrAddOnRef);
339 
340 		void MakeEmpty();
341 
342 	private:
343 		EditableCatalog();
344 		EditableCatalog(const EditableCatalog&);
345 		const EditableCatalog& operator= (const EditableCatalog&);
346 			// hide assignment, default- and copy-constructor
347 
348 };
349 
350 } // namespace BPrivate
351 
352 #endif /* _CATALOG_H_ */
353