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