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