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