From 5570fd11c032110ee0bbfd01a2265d810301687b Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Wed, 20 Jan 2010 22:44:34 +0000 Subject: [PATCH] - Locale kit : made the language class live. It now uses ICU as a backend as expected - Some changes in the locale roster to allow instanciating a language - Locale preflet : use this new API instead of directly calling ICU Side effect : all languages in Locale window are now displayed in the current locale. It makes more sense as otherwise the list would be unsortable. However it can get annoying if you mistakenly set a strange language as default. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@35210 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/os/locale/Language.h | 17 +++- headers/os/locale/LocaleRoster.h | 2 + src/kits/locale/Language.cpp | 122 +++++------------------- src/kits/locale/LocaleRoster.cpp | 10 ++ src/preferences/locale/LocaleWindow.cpp | 22 ++--- 5 files changed, 61 insertions(+), 112 deletions(-) diff --git a/headers/os/locale/Language.h b/headers/os/locale/Language.h index c947df9627..d5dddafec8 100644 --- a/headers/os/locale/Language.h +++ b/headers/os/locale/Language.h @@ -8,10 +8,18 @@ #define _LANGUAGE_H_ +#include #include #include +// We must not include the icu headers in there as it could mess up binary +// compatibility. +namespace icu_4_2 { + class Locale; +} + + enum script_direction { B_LEFT_TO_RIGHT = 0, B_RIGHT_TO_LEFT, @@ -24,11 +32,9 @@ class BLanguage { ~BLanguage(); // language name, e.g. "english", "deutsch" - const char *Name() const { return fName; } + status_t GetName(BString* name); // ISO-639 language code, e.g. "en", "de" - const char *Code() const { return fCode; } - // ISO-639 language family, e.g. "germanic" - const char *Family() const { return fFamily; } + const char* Code(); uint8 Direction() const; @@ -41,8 +47,9 @@ class BLanguage { BLanguage(const char *language); void Default(); - char *fName, *fCode, *fFamily, *fStrings[B_NUM_LANGUAGE_STRINGS]; + char *fStrings[B_NUM_LANGUAGE_STRINGS]; uint8 fDirection; + icu_4_2::Locale* fICULocale; }; #endif /* _LANGUAGE_H_ */ diff --git a/headers/os/locale/LocaleRoster.h b/headers/os/locale/LocaleRoster.h index 8b96f5b9fb..07ae49f3b6 100644 --- a/headers/os/locale/LocaleRoster.h +++ b/headers/os/locale/LocaleRoster.h @@ -41,6 +41,8 @@ class BLocaleRoster { status_t GetDefaultCountry(BCountry **) const; void SetDefaultCountry(BCountry *) const; + status_t GetLanguage(BLanguage** language, BString languageCode) const; + status_t GetPreferredLanguages(BMessage *) const; status_t SetPreferredLanguages(BMessage *); // the message contains one or more 'language'-string-fields diff --git a/src/kits/locale/Language.cpp b/src/kits/locale/Language.cpp index e113d91a86..0c31758eb2 100644 --- a/src/kits/locale/Language.cpp +++ b/src/kits/locale/Language.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include @@ -14,6 +15,10 @@ #include #include +#include + +#include + static const char *gBuiltInStrings[] = { "Yesterday", @@ -70,113 +75,24 @@ static const char *gBuiltInStrings[] = { }; -static char * -TrimCopy(char *string) -{ - while (isspace(*string)) - string++; - - int32 length = strlen(string); - while (length-- > 0 && isspace(string[length])) - string[length] = '\0'; - - if (length < 0) - return NULL; - - return strdup(string); -} - - // #pragma mark - BLanguage::BLanguage(const char *language) : - fName(NULL), - fCode(NULL), - fFamily(NULL), fDirection(B_LEFT_TO_RIGHT) { + fICULocale = new icu_4_2::Locale(language); + for (int32 i = B_NUM_LANGUAGE_STRINGS;i-- > 0;) fStrings[i] = NULL; - - if (language == NULL) { - Default(); - return; - } - - char name[B_FILE_NAME_LENGTH]; - sprintf(name, "locale/languages/%s.language", language); - - BPath path; - if (find_directory(B_SYSTEM_DATA_DIRECTORY, &path) < B_OK) { - Default(); - return; - } - - path.Append(name); - - FILE *file = fopen(path.Path(), "r"); - if (file == NULL) { - Default(); - return; - } - - int32 count = -2; - while (fgets(name, B_FILE_NAME_LENGTH, file) != NULL) { - if (count == -2) { - char *family = strchr(name, ','); - if (family == NULL) - break; - *family++ = '\0'; - - // set the direction of writing - char *direction = strchr(family, ','); - if (direction != NULL) { - *direction++ = '\0'; - direction = TrimCopy(direction); - - if (!strcasecmp(direction, "ltr")) - fDirection = B_LEFT_TO_RIGHT; - else if (!strcasecmp(direction, "rtl")) - fDirection = B_RIGHT_TO_LEFT; - else if (!strcasecmp(direction, "ttb")) - fDirection = B_TOP_TO_BOTTOM; - - free(direction); - } - - fName = strdup(language); - fCode = TrimCopy(name); - fFamily = TrimCopy(family); - count++; - } else if (count == -1) { - if (!strcmp(name,"--\n")) - count++; - } else if (count < B_NUM_LANGUAGE_STRINGS) { - char *string = TrimCopy(name); - if (string == NULL) - continue; - - fStrings[count++] = string; - } - } - - if (count < 0) - Default(); - - fclose(file); } BLanguage::~BLanguage() { - if (fName != NULL) - free(fName); - if (fCode != NULL) - free(fCode); - if (fFamily != NULL) - free(fFamily); + if (fICULocale != NULL) + delete fICULocale; for (int32 i = B_NUM_LANGUAGE_STRINGS;i-- > 0;) free(fStrings[i]); @@ -186,9 +102,7 @@ BLanguage::~BLanguage() void BLanguage::Default() { - fName = strdup("english"); - fCode = strdup("en"); - fFamily = strdup("germanic"); + fICULocale = new icu_4_2::Locale("en"); fDirection = B_LEFT_TO_RIGHT; for (int32 i = B_NUM_LANGUAGE_STRINGS;i-- > 0;) { @@ -214,3 +128,19 @@ BLanguage::GetString(uint32 id) const return fStrings[id - B_LANGUAGE_STRINGS_BASE]; } + +status_t +BLanguage::GetName(BString* name) +{ + UnicodeString s; + fICULocale->getDisplayLanguage(s); + BStringByteSink converter(name); + s.toUTF8(converter); + return B_OK; +} + +const char* +BLanguage::Code() +{ + return fICULocale->getLanguage(); +} diff --git a/src/kits/locale/LocaleRoster.cpp b/src/kits/locale/LocaleRoster.cpp index badb8f518c..1d1291ca8a 100644 --- a/src/kits/locale/LocaleRoster.cpp +++ b/src/kits/locale/LocaleRoster.cpp @@ -453,6 +453,16 @@ BLocaleRoster::GetDefaultCountry(BCountry **country) const } +status_t +BLocaleRoster::GetLanguage(BLanguage **language, BString languageCode) const +{ + if (!language) + return B_BAD_VALUE; + *language = new(std::nothrow) BLanguage(languageCode); + return B_OK; +} + + void BLocaleRoster::SetDefaultCountry(BCountry * newDefault) const { diff --git a/src/preferences/locale/LocaleWindow.cpp b/src/preferences/locale/LocaleWindow.cpp index 6e17c94ed9..64f5a51c9f 100644 --- a/src/preferences/locale/LocaleWindow.cpp +++ b/src/preferences/locale/LocaleWindow.cpp @@ -344,22 +344,22 @@ LocaleWindow::LocaleWindow() if (be_locale_roster->GetInstalledLanguages(&installedLanguages) == B_OK) { - BString currentLanguage; + BString currentLanguageCode; + BString currentLanguageName; for (int i = 0; installedLanguages.FindString("langs", - i, ¤tLanguage) == B_OK; i++) { + i, ¤tLanguageCode) == B_OK; i++) { // Now get an human-readable, loacalized name for each language // TODO: sort them using collators. - Locale currentLocale - = Locale::createFromName(currentLanguage.String()); - UnicodeString languageFullName; - BString str; - BStringByteSink bbs(&str); - currentLocale.getDisplayName(currentLocale, languageFullName); - languageFullName.toUTF8(bbs); - LanguageListItem* si - = new LanguageListItem(str, currentLanguage.String()); + BLanguage* currentLanguage; + be_locale_roster->GetLanguage(¤tLanguage, + currentLanguageCode.String()); + currentLanguageName.Truncate(0); + currentLanguage->GetName(¤tLanguageName); + LanguageListItem* si = new LanguageListItem(currentLanguageName, + currentLanguageCode.String()); fLanguageListView->AddItem(si); + delete currentLanguage; } fLanguageListView->SortItems(compare_list_items);