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);