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