Author: axeld Date: 2011-05-25 19:09:30 +0200 (Wed, 25 May 2011) New Revision: 41744 Changeset: https://dev.haiku-os.org/changeset/41744 Modified: haiku/trunk/headers/os/locale/Language.h haiku/trunk/headers/os/locale/LocaleRoster.h haiku/trunk/src/kits/locale/Language.cpp haiku/trunk/src/kits/locale/LocaleRoster.cpp Log: * Added BLanguage::GetIcon(), and BLocaleRoster::GetFlagIconForLanguage(). The former just calls the latter. Getting the flag for a language is pretty simplistic for now, but it won't return the wrong flag, just only a few known ones (should be enough for ReadOnlyBootPrompt, at least). * Ordered methods in declaration order. Modified: haiku/trunk/headers/os/locale/Language.h =================================================================== --- haiku/trunk/headers/os/locale/Language.h 2011-05-25 16:04:28 UTC (rev 41743) +++ haiku/trunk/headers/os/locale/Language.h 2011-05-25 17:09:30 UTC (rev 41744) @@ -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 <SupportDefs.h> +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 @@ 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 @@ uint8 Direction() const; - status_t SetTo(const char* language); + BLanguage& operator=(const BLanguage& source); - const char* GetString(uint32 id) const; - class Private; private: friend class Private; -// BString fStrings[B_NUM_LANGUAGE_STRINGS]; uint8 fDirection; icu_44::Locale* fICULocale; }; Modified: haiku/trunk/headers/os/locale/LocaleRoster.h =================================================================== --- haiku/trunk/headers/os/locale/LocaleRoster.h 2011-05-25 16:04:28 UTC (rev 41743) +++ haiku/trunk/headers/os/locale/LocaleRoster.h 2011-05-25 17:09:30 UTC (rev 41744) @@ -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 @@ 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, Modified: haiku/trunk/src/kits/locale/Language.cpp =================================================================== --- haiku/trunk/src/kits/locale/Language.cpp 2011-05-25 16:04:28 UTC (rev 41743) +++ haiku/trunk/src/kits/locale/Language.cpp 2011-05-25 17:09:30 UTC (rev 41744) @@ -1,5 +1,5 @@ /* - * Copyright 2003-2009, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx + * Copyright 2003-2011, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx * Distributed under the terms of the MIT License. */ @@ -72,43 +72,6 @@ } -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,7 +116,29 @@ } +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 { return fICULocale->getLanguage(); @@ -212,3 +197,26 @@ { 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; +} Modified: haiku/trunk/src/kits/locale/LocaleRoster.cpp =================================================================== --- haiku/trunk/src/kits/locale/LocaleRoster.cpp 2011-05-25 16:04:28 UTC (rev 41743) +++ haiku/trunk/src/kits/locale/LocaleRoster.cpp 2011-05-25 17:09:30 UTC (rev 41744) @@ -66,6 +66,59 @@ // 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 @@ 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); @@ -285,6 +338,25 @@ 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 @@ } +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,61 +495,7 @@ } -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) {