diff --git a/headers/os/locale/Language.h b/headers/os/locale/Language.h index cf9eb9af6c..15ac380e11 100644 --- a/headers/os/locale/Language.h +++ b/headers/os/locale/Language.h @@ -1,5 +1,5 @@ /* - * Copyright 2003-2010, Haiku, Inc. + * Copyright 2003-2011, Haiku, Inc. * Distributed under the terms of the MIT License. */ #ifndef _LANGUAGE_H_ @@ -11,6 +11,8 @@ #include +class BBitmap; + // We must not include the icu headers in there as it could mess up binary // compatibility. namespace icu_44 { @@ -32,12 +34,14 @@ public: BLanguage(const BLanguage& other); ~BLanguage(); - BLanguage& operator=(const BLanguage& source); + status_t SetTo(const char* language); status_t GetNativeName(BString& name) const; status_t GetName(BString& name, const BLanguage* displayLanguage = NULL ) const; + const char* GetString(uint32 id) const; + status_t GetIcon(BBitmap* result) const; const char* Code() const; // ISO-639-1 @@ -53,15 +57,12 @@ public: uint8 Direction() const; - status_t SetTo(const char* language); - - const char* GetString(uint32 id) const; + BLanguage& operator=(const BLanguage& source); class Private; private: friend class Private; -// BString fStrings[B_NUM_LANGUAGE_STRINGS]; uint8 fDirection; icu_44::Locale* fICULocale; }; diff --git a/headers/os/locale/LocaleRoster.h b/headers/os/locale/LocaleRoster.h index a5fc1887c0..0bff1b1b0d 100644 --- a/headers/os/locale/LocaleRoster.h +++ b/headers/os/locale/LocaleRoster.h @@ -1,5 +1,5 @@ /* - * Copyright 2003-2010, Haiku. All rights reserved. + * Copyright 2003-2011, Haiku. All rights reserved. * Distributed under the terms of the MIT license. */ #ifndef _LOCALE_ROSTER_H_ @@ -51,6 +51,8 @@ public: status_t GetFlagIconForCountry(BBitmap* flagIcon, const char* countryCode); + status_t GetFlagIconForLanguage(BBitmap* flagIcon, + const char* languageCode); status_t GetAvailableCatalogs(BMessage* message, const char* sigPattern = NULL, diff --git a/src/kits/locale/Language.cpp b/src/kits/locale/Language.cpp index b61f25fab2..919c0b7a8c 100644 --- a/src/kits/locale/Language.cpp +++ b/src/kits/locale/Language.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2003-2009, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2003-2011, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. */ @@ -72,43 +72,6 @@ BLanguage::SetTo(const char* language) } -BLanguage& BLanguage::operator=(const BLanguage& source) -{ - if (&source != this) { - delete fICULocale; - - fICULocale = source.fICULocale != NULL - ? source.fICULocale->clone() - : NULL; - fDirection = source.fDirection; - } - - return *this; -} - - -uint8 -BLanguage::Direction() const -{ - return fDirection; -} - - -const char* -BLanguage::GetString(uint32 id) const -{ - if (id < B_LANGUAGE_STRINGS_BASE - || id >= B_LANGUAGE_STRINGS_BASE + B_NUM_LANGUAGE_STRINGS) - return NULL; - - return NULL; - - // TODO: fetch string from ICU - -// return fStrings[id - B_LANGUAGE_STRINGS_BASE]; -} - - status_t BLanguage::GetNativeName(BString& name) const { @@ -153,6 +116,28 @@ BLanguage::GetName(BString& name, const BLanguage* displayLanguage) const } +status_t +BLanguage::GetIcon(BBitmap* result) const +{ + return BLocaleRoster::Default()->GetFlagIconForCountry(result, Code()); +} + + +const char* +BLanguage::GetString(uint32 id) const +{ + if (id < B_LANGUAGE_STRINGS_BASE + || id >= B_LANGUAGE_STRINGS_BASE + B_NUM_LANGUAGE_STRINGS) + return NULL; + + return NULL; + + // TODO: fetch string from ICU + +// return fStrings[id - B_LANGUAGE_STRINGS_BASE]; +} + + const char* BLanguage::Code() const { @@ -212,3 +197,26 @@ BLanguage::IsVariant() const { return Variant() != NULL; } + + +uint8 +BLanguage::Direction() const +{ + return fDirection; +} + + +BLanguage& +BLanguage::operator=(const BLanguage& source) +{ + if (&source != this) { + delete fICULocale; + + fICULocale = source.fICULocale != NULL + ? source.fICULocale->clone() + : NULL; + fDirection = source.fDirection; + } + + return *this; +} diff --git a/src/kits/locale/LocaleRoster.cpp b/src/kits/locale/LocaleRoster.cpp index 6966a4e138..fd77f1cfd7 100644 --- a/src/kits/locale/LocaleRoster.cpp +++ b/src/kits/locale/LocaleRoster.cpp @@ -66,6 +66,59 @@ int32 BLocaleRoster::kEmbeddedCatResId = 0xCADA; // this may live in an app- or add-on-file +static const char* +country_code_for_language(const BLanguage& language) +{ + if (language.IsCountrySpecific()) + return language.CountryCode(); + + // TODO: implement for real! For now, we just map some well known + // languages to countries to make ReadOnlyBootPrompt happy. + switch ((tolower(language.Code()[0]) << 8) | tolower(language.Code()[1])) { + case 'be': // Belarus + return "BY"; + case 'cs': // Czech Republic + return "CZ"; + case 'da': // Denmark + return "DK"; + case 'en': // United Kingdom + return "GB"; + case 'ja': // Japan + return "JP"; + case 'ko': // South Korea + return "KR"; + case 'nb': // Norway + return "NO"; + case 'sv': // Sweden + return "SE"; + case 'uk': // Ukraine + return "UA"; + case 'zh': // China + return "CN"; + + // Languages with a matching country name + case 'de': // Germany + case 'es': // Spain + case 'fi': // Finland + case 'fr': // France + case 'hu': // Hungary + case 'it': // Italy + case 'lt': // Lithuania + case 'nl': // Netherlands + case 'pl': // Poland + case 'pt': // Portugal + case 'ro': // Romania + case 'ru': // Russia + return language.Code(); + } + + return NULL; +} + + +// #pragma mark - + + BLocaleRoster::BLocaleRoster() { } @@ -242,7 +295,7 @@ status_t BLocaleRoster::GetFlagIconForCountry(BBitmap* flagIcon, const char* countryCode) { if (countryCode == NULL) - return B_BAD_DATA; + return B_BAD_VALUE; RosterData* rosterData = RosterData::Default(); BAutolock lock(rosterData->fLock); @@ -284,6 +337,25 @@ BLocaleRoster::GetFlagIconForCountry(BBitmap* flagIcon, const char* countryCode) } +status_t +BLocaleRoster::GetFlagIconForLanguage(BBitmap* flagIcon, + const char* languageCode) +{ + if (languageCode == NULL || languageCode[0] == '\0' + || languageCode[1] == '\0') + return B_BAD_VALUE; + + // TODO: Languages like Esperanto have a flag, but no country + + BLanguage language(languageCode); + const char* countryCode = country_code_for_language(language); + if (countryCode == NULL) + return B_NAME_NOT_FOUND; + + return GetFlagIconForCountry(flagIcon, countryCode); +} + + status_t BLocaleRoster::GetAvailableCatalogs(BMessage* languageList, const char* sigPattern, const char* langPattern, int32 fingerprint) const @@ -312,6 +384,60 @@ BLocaleRoster::GetAvailableCatalogs(BMessage* languageList, } +bool +BLocaleRoster::IsFilesystemTranslationPreferred() const +{ + RosterData* rosterData = RosterData::Default(); + BAutolock lock(rosterData->fLock); + if (!lock.IsLocked()) + return B_ERROR; + + return rosterData->fIsFilesystemTranslationPreferred; +} + + +/*! \brief Looks up a localized filename from a catalog. + \param localizedFileName A pre-allocated BString object for the result + of the lookup. + \param ref An entry_ref with an attribute holding data for catalog lookup. + \param traverse A boolean to decide if symlinks are to be traversed. + \return + - \c B_OK: success + - \c B_ENTRY_NOT_FOUND: failure. Attribute not found, entry not found + in catalog, etc + - other error codes: failure + + Attribute format: "signature:context:string" + (no colon in any of signature, context and string) + + Lookup is done for the top preferred language, only. + Lookup fails if a comment is present in the catalog entry. +*/ +status_t +BLocaleRoster::GetLocalizedFileName(BString& localizedFileName, + const entry_ref& ref, bool traverse) +{ + BString signature; + BString context; + BString string; + + status_t status = _PrepareCatalogEntry(ref, signature, context, string, + traverse); + + if (status != B_OK) + return status; + + BCatalog catalog(signature); + const char* temp = catalog.GetString(string, context); + + if (temp == NULL) + return B_ENTRY_NOT_FOUND; + + localizedFileName = temp; + return B_OK; +} + + BCatalog* BLocaleRoster::_GetCatalog(BCatalog* catalog, vint32* catalogInitStatus) { @@ -369,60 +495,6 @@ BLocaleRoster::_GetCatalog(BCatalog* catalog, vint32* catalogInitStatus) } -bool -BLocaleRoster::IsFilesystemTranslationPreferred() const -{ - RosterData* rosterData = RosterData::Default(); - BAutolock lock(rosterData->fLock); - if (!lock.IsLocked()) - return B_ERROR; - - return rosterData->fIsFilesystemTranslationPreferred; -} - - -/*! \brief Looks up a localized filename from a catalog. - \param localizedFileName A pre-allocated BString object for the result - of the lookup. - \param ref An entry_ref with an attribute holding data for catalog lookup. - \param traverse A boolean to decide if symlinks are to be traversed. - \return - - \c B_OK: success - - \c B_ENTRY_NOT_FOUND: failure. Attribute not found, entry not found - in catalog, etc - - other error codes: failure - - Attribute format: "signature:context:string" - (no colon in any of signature, context and string) - - Lookup is done for the top preferred language, only. - Lookup fails if a comment is present in the catalog entry. -*/ -status_t -BLocaleRoster::GetLocalizedFileName(BString& localizedFileName, - const entry_ref& ref, bool traverse) -{ - BString signature; - BString context; - BString string; - - status_t status = _PrepareCatalogEntry(ref, signature, context, string, - traverse); - - if (status != B_OK) - return status; - - BCatalog catalog(signature); - const char* temp = catalog.GetString(string, context); - - if (temp == NULL) - return B_ENTRY_NOT_FOUND; - - localizedFileName = temp; - return B_OK; -} - - status_t BLocaleRoster::_PrepareCatalogEntry(const entry_ref& ref, BString& signature, BString& context, BString& string, bool traverse)