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