diff --git a/headers/os/locale/Country.h b/headers/os/locale/Country.h index 45d050e649..0d36873b92 100644 --- a/headers/os/locale/Country.h +++ b/headers/os/locale/Country.h @@ -55,69 +55,16 @@ public: const char* GetLocalizedString(uint32 id) const; - // Date - - status_t FormatDate(char* string, size_t maxSize, - time_t time, bool longFormat); - status_t FormatDate(BString* string, time_t time, - bool longFormat); - status_t FormatDate(BString* string, - int*& fieldPositions, int& fieldCount, - time_t time, bool longFormat); - status_t GetDateFields(BDateElement*& fields, - int& fieldCount, bool longFormat) const; - status_t GetDateFormat(BString&, bool longFormat) const; - status_t SetDateFormat(const char* formatString, - bool longFormat = true); - - int StartOfWeek() const; - - // Time - - status_t FormatTime(char* string, size_t maxSize, - time_t time, bool longFormat); - status_t FormatTime(BString* string, time_t time, - bool longFormat); - status_t FormatTime(BString* string, - int*& fieldPositions, int& fieldCount, - time_t time, bool longFormat); - status_t GetTimeFields(BDateElement*& fields, - int& fieldCount, bool longFormat) const; - - status_t SetTimeFormat(const char* formatString, - bool longFormat = true); - status_t GetTimeFormat(BString& out, - bool longFormat) const; - - // numbers - - status_t FormatNumber(char* string, size_t maxSize, - double value); - status_t FormatNumber(BString* string, double value); - status_t FormatNumber(char* string, size_t maxSize, - int32 value); - status_t FormatNumber(BString* string, int32 value); - // measurements int8 Measurement() const; - // monetary - - ssize_t FormatMonetary(char* string, size_t maxSize, - double value); - ssize_t FormatMonetary(BString* string, double value); - // timezones int GetTimeZones(BList& timezones) const; private: icu_44::Locale* fICULocale; - BString fLongDateFormat; - BString fShortDateFormat; - BString fLongTimeFormat; - BString fShortTimeFormat; }; diff --git a/headers/os/locale/Locale.h b/headers/os/locale/Locale.h index 300515c30a..52069b0729 100644 --- a/headers/os/locale/Locale.h +++ b/headers/os/locale/Locale.h @@ -17,12 +17,20 @@ class BString; class BLocale { public: - BLocale(); + BLocale(const char* languageAndCountryCode + = "en_US"); + BLocale(const BLocale& other); + BLocale& operator=(const BLocale& other); ~BLocale(); const BCollator* Collator() const { return &fCollator; } const BCountry* Country() const { return &fCountry; } const BLanguage* Language() const { return &fLanguage; } + const char* Code() const; + + void SetCountry(const BCountry& newCountry); + void SetCollator(const BCollator& newCollator); + void SetLanguage(const char* languageCode); // see definitions in LocaleStrings.h const char* GetString(uint32 id); @@ -35,16 +43,54 @@ public: void FormatDateTime(BString* buffer, const char* fmt, time_t value); - // Country short-hands, TODO: all these should go, once the - // Date...Format classes are done - void FormatDate(char* target, size_t maxSize, - time_t value, bool longFormat); - void FormatDate(BString* target, time_t value, + // Date + + status_t FormatDate(char* string, size_t maxSize, + time_t time, bool longFormat); + status_t FormatDate(BString* string, time_t time, bool longFormat); - void FormatTime(char* target, size_t maxSize, - time_t value, bool longFormat); - void FormatTime(BString* target, time_t value, + status_t FormatDate(BString* string, + int*& fieldPositions, int& fieldCount, + time_t time, bool longFormat); + status_t GetDateFields(BDateElement*& fields, + int& fieldCount, bool longFormat) const; + status_t GetDateFormat(BString&, bool longFormat) const; + status_t SetDateFormat(const char* formatString, + bool longFormat = true); + + int StartOfWeek() const; + + // Time + + status_t FormatTime(char* string, size_t maxSize, + time_t time, bool longFormat); + status_t FormatTime(BString* string, time_t time, bool longFormat); + status_t FormatTime(BString* string, + int*& fieldPositions, int& fieldCount, + time_t time, bool longFormat); + status_t GetTimeFields(BDateElement*& fields, + int& fieldCount, bool longFormat) const; + + status_t SetTimeFormat(const char* formatString, + bool longFormat = true); + status_t GetTimeFormat(BString& out, + bool longFormat) const; + + // numbers + + status_t FormatNumber(char* string, size_t maxSize, + double value); + status_t FormatNumber(BString* string, double value); + status_t FormatNumber(char* string, size_t maxSize, + int32 value); + status_t FormatNumber(BString* string, int32 value); + + // monetary + + ssize_t FormatMonetary(char* string, size_t maxSize, + double value); + ssize_t FormatMonetary(BString* string, double value); // Collator short-hands int StringCompare(const char* s1, @@ -59,44 +105,16 @@ protected: BCollator fCollator; BCountry fCountry; BLanguage fLanguage; + + icu_44::Locale* fICULocale; + BString fLongDateFormat; + BString fShortDateFormat; + BString fLongTimeFormat; + BString fShortTimeFormat; }; -// global objects -extern BLocale* be_locale; - - -//---------------------------------------------------------------------- -//--- country short-hands inlines --- -inline void -BLocale::FormatDate(char* target, size_t maxSize, time_t timer, bool longFormat) -{ - fCountry.FormatDate(target, maxSize, timer, longFormat); -} - - -inline void -BLocale::FormatDate(BString* target, time_t timer, bool longFormat) -{ - fCountry.FormatDate(target, timer, longFormat); -} - - -inline void -BLocale::FormatTime(char* target, size_t maxSize, time_t timer, bool longFormat) -{ - fCountry.FormatTime(target, maxSize, timer, longFormat); -} - - -inline void -BLocale::FormatTime(BString* target, time_t timer, bool longFormat) -{ - fCountry.FormatTime(target, timer, longFormat); -} - - -//--- locale short-hands inlines --- +//--- collator short-hands inlines --- // #pragma mark - inline int diff --git a/headers/os/locale/LocaleRoster.h b/headers/os/locale/LocaleRoster.h index 65aa00fb26..2f84da44a5 100644 --- a/headers/os/locale/LocaleRoster.h +++ b/headers/os/locale/LocaleRoster.h @@ -31,6 +31,7 @@ public: status_t GetDefaultCollator(BCollator* collator) const; status_t GetDefaultLanguage(BLanguage* language) const; status_t GetDefaultCountry(BCountry* country) const; + status_t GetDefaultLocale(BLocale* locale) const; status_t GetDefaultTimeZone(BTimeZone* timezone) const; status_t GetLanguage(const char* languageCode, diff --git a/headers/private/locale/MutableLocaleRoster.h b/headers/private/locale/MutableLocaleRoster.h index 402c15f1fd..ab10214e06 100644 --- a/headers/private/locale/MutableLocaleRoster.h +++ b/headers/private/locale/MutableLocaleRoster.h @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -33,6 +34,7 @@ public: ~MutableLocaleRoster(); status_t SetDefaultCountry(const BCountry& country); + status_t SetDefaultLocale(const BLocale& locale); status_t SetDefaultTimeZone(const BTimeZone& zone); status_t SetPreferredLanguages(const BMessage* message); @@ -106,9 +108,7 @@ struct RosterData { BList fCatalogAddOnInfos; BMessage fPreferredLanguages; - BCollator fDefaultCollator; - BCountry fDefaultCountry; - BLanguage fDefaultLanguage; + BLocale fDefaultLocale; BTimeZone fDefaultTimeZone; RosterData(); @@ -122,6 +122,7 @@ struct RosterData { const void* right); status_t SetDefaultCountry(const BCountry& country); + status_t SetDefaultLocale(const BLocale& locale); status_t SetDefaultTimeZone(const BTimeZone& zone); status_t SetPreferredLanguages(const BMessage* msg); private: @@ -132,6 +133,7 @@ private: status_t _SaveTimeSettings(); status_t _SetDefaultCountry(const BCountry& country); + status_t _SetDefaultLocale(const BLocale& locale); status_t _SetDefaultTimeZone(const BTimeZone& zone); status_t _SetPreferredLanguages(const BMessage* msg); diff --git a/src/apps/aboutsystem/AboutSystem.cpp b/src/apps/aboutsystem/AboutSystem.cpp index b9e5ed4706..d3484530ce 100644 --- a/src/apps/aboutsystem/AboutSystem.cpp +++ b/src/apps/aboutsystem/AboutSystem.cpp @@ -188,8 +188,9 @@ TranslationComparator(const void* left, const void* right) language->GetTranslatedName(rightName); delete language; - return be_locale->Collator()->Compare(leftName.String(), - rightName.String()); + BCollator collator; + be_locale_roster->GetDefaultCollator(&collator); + return collator.Compare(leftName.String(), rightName.String()); } diff --git a/src/apps/deskbar/CalendarMenuWindow.cpp b/src/apps/deskbar/CalendarMenuWindow.cpp index c5bfb3465c..fd224456d2 100644 --- a/src/apps/deskbar/CalendarMenuWindow.cpp +++ b/src/apps/deskbar/CalendarMenuWindow.cpp @@ -89,10 +89,10 @@ CalendarMenuWindow::CalendarMenuWindow(BPoint where) fCalendarView(NULL), fSuppressFirstClose(true) { - BCountry country; - be_locale_roster->GetDefaultCountry(&country); + BLocale locale; + be_locale_roster->GetDefaultLocale(&locale); BPrivate::week_start startOfWeek - = (BPrivate::week_start)country.StartOfWeek(); + = (BPrivate::week_start)locale.StartOfWeek(); RemoveShortcut('H', B_COMMAND_KEY | B_CONTROL_KEY); AddShortcut('W', B_COMMAND_KEY, new BMessage(B_QUIT_REQUESTED)); diff --git a/src/apps/deskbar/TimeView.cpp b/src/apps/deskbar/TimeView.cpp index d6116fe23b..8595c30276 100644 --- a/src/apps/deskbar/TimeView.cpp +++ b/src/apps/deskbar/TimeView.cpp @@ -91,7 +91,7 @@ TTimeView::TTimeView(float maxWidth, float height, bool showSeconds, fLastDateStr[0] = 0; fNeedToUpdate = true; - be_locale_roster->GetDefaultCountry(&fCountry); + be_locale_roster->GetDefaultLocale(&fLocale); } @@ -105,7 +105,7 @@ TTimeView::TTimeView(BMessage* data) data->FindBool("interval", &fInterval); fShowingDate = false; - be_locale_roster->GetDefaultCountry(&fCountry); + be_locale_roster->GetDefaultCountry(&fLocale); } #endif @@ -313,7 +313,7 @@ TTimeView::GetCurrentTime() fMinute = time.tm_min; fHour = time.tm_hour; - fCountry.FormatTime(fTimeStr, 64, fTime, fShowSeconds); + fLocale.FormatTime(fTimeStr, 64, fTime, fShowSeconds); } @@ -322,7 +322,7 @@ TTimeView::GetCurrentDate() { char tmp[64]; - fCountry.FormatDate(tmp, 64, fTime, fFullDate && CanShowFullDate()); + fLocale.FormatDate(tmp, 64, fTime, fFullDate && CanShowFullDate()); // remove leading 0 from date when month is less than 10 (MM/DD/YY) // or remove leading 0 from date when day is less than 10 (DD/MM/YY) @@ -465,7 +465,7 @@ TTimeView::AllowFullDate(bool allow) void TTimeView::Update() { - be_locale_roster->GetDefaultCountry(&fCountry); + be_locale_roster->GetDefaultLocale(&fLocale); GetCurrentTime(); GetCurrentDate(); diff --git a/src/apps/deskbar/TimeView.h b/src/apps/deskbar/TimeView.h index 06584f9566..aeed96852d 100644 --- a/src/apps/deskbar/TimeView.h +++ b/src/apps/deskbar/TimeView.h @@ -36,7 +36,7 @@ All rights reserved. #include -#include +#include #include #include @@ -129,7 +129,7 @@ class TTimeView : public BView { BMessenger fCalendarWindow; BMessageRunner* fLongClickMessageRunner; - BCountry fCountry; // For date and time localizing purposes + BLocale fLocale; // For date and time localizing purposes }; diff --git a/src/bin/dstcheck.cpp b/src/bin/dstcheck.cpp index 5c2c40bd34..1d0acc005c 100644 --- a/src/bin/dstcheck.cpp +++ b/src/bin/dstcheck.cpp @@ -84,8 +84,8 @@ TimedAlert::GetLabel(BString &string) time(&t); localtime_r(&t, &tm); - BCountry here; - be_locale_roster->GetDefaultCountry(&here); + BLocale here; + be_locale_roster->GetDefaultLocale(&here); here.FormatTime(timestring, 15, t, false); diff --git a/src/kits/locale/Country.cpp b/src/kits/locale/Country.cpp index 37a1995a69..e7612d10b7 100644 --- a/src/kits/locale/Country.cpp +++ b/src/kits/locale/Country.cpp @@ -8,7 +8,6 @@ #include #include -#include #include #include #include @@ -16,10 +15,7 @@ #include #include -#include -#include -#include -#include +#include #include #include @@ -28,23 +24,11 @@ #include #include #include -#include #define ICU_VERSION icu_44 -using BPrivate::ObjectDeleter; -using BPrivate::B_WEEK_START_MONDAY; -using BPrivate::B_WEEK_START_SUNDAY; - - -static DateFormat* CreateDateFormat(bool longFormat, const Locale& locale, - const BString& format); -static DateFormat* CreateTimeFormat(bool longFormat, const Locale& locale, - const BString& format); - - BCountry::BCountry(const char* languageCode, const char* countryCode) : fICULocale(new ICU_VERSION::Locale(languageCode, countryCode)) @@ -61,11 +45,7 @@ BCountry::BCountry(const char* languageAndCountryCode) BCountry::BCountry(const BCountry& other) : - fICULocale(new ICU_VERSION::Locale(*other.fICULocale)), - fLongDateFormat(other.fLongDateFormat), - fShortDateFormat(other.fShortDateFormat), - fLongTimeFormat(other.fLongTimeFormat), - fShortTimeFormat(other.fShortTimeFormat) + fICULocale(new ICU_VERSION::Locale(*other.fICULocale)) { } @@ -76,13 +56,7 @@ BCountry::operator=(const BCountry& other) if (this == &other) return *this; - delete fICULocale; - fICULocale = new ICU_VERSION::Locale(*other.fICULocale); - - fLongDateFormat = other.fLongDateFormat; - fShortDateFormat = other.fShortDateFormat; - fLongTimeFormat = other.fLongTimeFormat; - fShortTimeFormat = other.fShortTimeFormat; + *fICULocale = *other.fICULocale; return *this; } @@ -146,467 +120,6 @@ BCountry::GetIcon(BBitmap* result) const } -// #pragma mark - Date - - -status_t -BCountry::FormatDate(char* string, size_t maxSize, time_t time, bool longFormat) -{ - ObjectDeleter dateFormatter = CreateDateFormat(longFormat, - *fICULocale, longFormat ? fLongDateFormat : fShortDateFormat); - if (dateFormatter.Get() == NULL) - return B_NO_MEMORY; - - UnicodeString ICUString; - ICUString = dateFormatter->format((UDate)time * 1000, ICUString); - - CheckedArrayByteSink stringConverter(string, maxSize); - - ICUString.toUTF8(stringConverter); - - if (stringConverter.Overflowed()) - return B_BAD_VALUE; - - return B_OK; -} - - -status_t -BCountry::FormatDate(BString *string, time_t time, bool longFormat) -{ - string->Truncate(0); - // We make the string empty, this way even in cases where ICU fail we at - // least return something sane - ObjectDeleter dateFormatter = CreateDateFormat(longFormat, - *fICULocale, longFormat ? fLongDateFormat : fShortDateFormat); - if (dateFormatter.Get() == NULL) - return B_NO_MEMORY; - - UnicodeString ICUString; - ICUString = dateFormatter->format((UDate)time * 1000, ICUString); - - BStringByteSink stringConverter(string); - - ICUString.toUTF8(stringConverter); - - return B_OK; -} - - -status_t -BCountry::FormatDate(BString* string, int*& fieldPositions, int& fieldCount, - time_t time, bool longFormat) -{ - string->Truncate(0); - - ObjectDeleter dateFormatter = CreateDateFormat(longFormat, - *fICULocale, longFormat ? fLongDateFormat : fShortDateFormat); - if (dateFormatter.Get() == NULL) - return B_NO_MEMORY; - - fieldPositions = NULL; - UErrorCode error = U_ZERO_ERROR; - ICU_VERSION::FieldPositionIterator positionIterator; - UnicodeString ICUString; - ICUString = dateFormatter->format((UDate)time * 1000, ICUString, - &positionIterator, error); - - if (error != U_ZERO_ERROR) - return B_ERROR; - - ICU_VERSION::FieldPosition field; - std::vector fieldPosStorage; - fieldCount = 0; - while (positionIterator.next(field)) { - fieldPosStorage.push_back(field.getBeginIndex()); - fieldPosStorage.push_back(field.getEndIndex()); - fieldCount += 2; - } - - fieldPositions = (int*) malloc(fieldCount * sizeof(int)); - - for (int i = 0 ; i < fieldCount ; i++ ) - fieldPositions[i] = fieldPosStorage[i]; - - BStringByteSink stringConverter(string); - - ICUString.toUTF8(stringConverter); - - return B_OK; -} - - -status_t -BCountry::GetDateFormat(BString& format, bool longFormat) const -{ - if (longFormat && fLongDateFormat.Length() > 0) - format = fLongDateFormat; - else if (!longFormat && fShortDateFormat.Length() > 0) - format = fShortDateFormat; - else { - format.Truncate(0); - - ObjectDeleter dateFormatter = CreateDateFormat(longFormat, - *fICULocale, longFormat ? fLongDateFormat : fShortDateFormat); - if (dateFormatter.Get() == NULL) - return B_NO_MEMORY; - - SimpleDateFormat* dateFormatterImpl - = static_cast(dateFormatter.Get()); - - UnicodeString ICUString; - ICUString = dateFormatterImpl->toPattern(ICUString); - - BStringByteSink stringConverter(&format); - - ICUString.toUTF8(stringConverter); - } - - return B_OK; -} - - -status_t -BCountry::SetDateFormat(const char* formatString, bool longFormat) -{ -printf("FV::SetDateFormat: df='%s'\n", formatString); - if (longFormat) - fLongDateFormat = formatString; - else - fShortDateFormat = formatString; - - return B_OK; -} - - -status_t -BCountry::GetDateFields(BDateElement*& fields, int& fieldCount, - bool longFormat) const -{ - ObjectDeleter dateFormatter = CreateDateFormat(longFormat, - *fICULocale, longFormat ? fLongDateFormat : fShortDateFormat); - if (dateFormatter.Get() == NULL) - return B_NO_MEMORY; - - fields = NULL; - UErrorCode error = U_ZERO_ERROR; - ICU_VERSION::FieldPositionIterator positionIterator; - UnicodeString ICUString; - time_t now; - ICUString = dateFormatter->format((UDate)time(&now) * 1000, ICUString, - &positionIterator, error); - - if (U_FAILURE(error)) - return B_ERROR; - - ICU_VERSION::FieldPosition field; - std::vector fieldPosStorage; - fieldCount = 0; - while (positionIterator.next(field)) { - fieldPosStorage.push_back(field.getField()); - fieldCount ++; - } - - fields = (BDateElement*) malloc(fieldCount * sizeof(BDateElement)); - - for (int i = 0 ; i < fieldCount ; i++ ) { - switch (fieldPosStorage[i]) { - case UDAT_YEAR_FIELD: - fields[i] = B_DATE_ELEMENT_YEAR; - break; - case UDAT_MONTH_FIELD: - fields[i] = B_DATE_ELEMENT_MONTH; - break; - case UDAT_DATE_FIELD: - fields[i] = B_DATE_ELEMENT_DAY; - break; - default: - fields[i] = B_DATE_ELEMENT_INVALID; - break; - } - } - - return B_OK; -} - - -int -BCountry::StartOfWeek() const -{ - UErrorCode err = U_ZERO_ERROR; - Calendar* c = Calendar::createInstance(*fICULocale, err); - - if (err == U_ZERO_ERROR && c->getFirstDayOfWeek(err) == UCAL_SUNDAY) { - delete c; - return B_WEEK_START_SUNDAY; - } else { - delete c; - // Might be another day, but BeAPI will not handle it - return B_WEEK_START_MONDAY; - } -} - - -// #pragma mark - Time - - -status_t -BCountry::FormatTime(char* string, size_t maxSize, time_t time, bool longFormat) -{ - ObjectDeleter timeFormatter = CreateTimeFormat(longFormat, - *fICULocale, longFormat ? fLongTimeFormat : fShortTimeFormat); - if (timeFormatter.Get() == NULL) - return B_NO_MEMORY; - - UnicodeString ICUString; - ICUString = timeFormatter->format((UDate)time * 1000, ICUString); - - CheckedArrayByteSink stringConverter(string, maxSize); - - ICUString.toUTF8(stringConverter); - - if (stringConverter.Overflowed()) - return B_BAD_VALUE; - - return B_OK; -} - - -status_t -BCountry::FormatTime(BString* string, time_t time, bool longFormat) -{ - string->Truncate(0); - - ObjectDeleter timeFormatter = CreateTimeFormat(longFormat, - *fICULocale, longFormat ? fLongTimeFormat : fShortTimeFormat); - if (timeFormatter.Get() == NULL) - return B_NO_MEMORY; - - UnicodeString ICUString; - ICUString = timeFormatter->format((UDate)time * 1000, ICUString); - - BStringByteSink stringConverter(string); - - ICUString.toUTF8(stringConverter); - - return B_OK; -} - - -status_t -BCountry::FormatTime(BString* string, int*& fieldPositions, int& fieldCount, - time_t time, bool longFormat) -{ - string->Truncate(0); - - ObjectDeleter timeFormatter = CreateTimeFormat(longFormat, - *fICULocale, longFormat ? fLongTimeFormat : fShortTimeFormat); - if (timeFormatter.Get() == NULL) - return B_NO_MEMORY; - - fieldPositions = NULL; - UErrorCode error = U_ZERO_ERROR; - ICU_VERSION::FieldPositionIterator positionIterator; - UnicodeString ICUString; - ICUString = timeFormatter->format((UDate)time * 1000, ICUString, - &positionIterator, error); - - if (error != U_ZERO_ERROR) - return B_ERROR; - - ICU_VERSION::FieldPosition field; - std::vector fieldPosStorage; - fieldCount = 0; - while (positionIterator.next(field)) { - fieldPosStorage.push_back(field.getBeginIndex()); - fieldPosStorage.push_back(field.getEndIndex()); - fieldCount += 2; - } - - fieldPositions = (int*) malloc(fieldCount * sizeof(int)); - - for (int i = 0 ; i < fieldCount ; i++ ) - fieldPositions[i] = fieldPosStorage[i]; - - BStringByteSink stringConverter(string); - - ICUString.toUTF8(stringConverter); - - return B_OK; -} - - -status_t -BCountry::GetTimeFields(BDateElement*& fields, int& fieldCount, - bool longFormat) const -{ - ObjectDeleter timeFormatter = CreateTimeFormat(longFormat, - *fICULocale, longFormat ? fLongTimeFormat : fShortTimeFormat); - if (timeFormatter.Get() == NULL) - return B_NO_MEMORY; - - fields = NULL; - UErrorCode error = U_ZERO_ERROR; - ICU_VERSION::FieldPositionIterator positionIterator; - UnicodeString ICUString; - time_t now; - ICUString = timeFormatter->format((UDate)time(&now) * 1000, ICUString, - &positionIterator, error); - - if (error != U_ZERO_ERROR) - return B_ERROR; - - ICU_VERSION::FieldPosition field; - std::vector fieldPosStorage; - fieldCount = 0; - while (positionIterator.next(field)) { - fieldPosStorage.push_back(field.getField()); - fieldCount ++; - } - - fields = (BDateElement*) malloc(fieldCount * sizeof(BDateElement)); - - for (int i = 0 ; i < fieldCount ; i++ ) { - switch (fieldPosStorage[i]) { - case UDAT_HOUR_OF_DAY1_FIELD: - case UDAT_HOUR_OF_DAY0_FIELD: - case UDAT_HOUR1_FIELD: - case UDAT_HOUR0_FIELD: - fields[i] = B_DATE_ELEMENT_HOUR; - break; - case UDAT_MINUTE_FIELD: - fields[i] = B_DATE_ELEMENT_MINUTE; - break; - case UDAT_SECOND_FIELD: - fields[i] = B_DATE_ELEMENT_SECOND; - break; - case UDAT_AM_PM_FIELD: - fields[i] = B_DATE_ELEMENT_AM_PM; - break; - default: - fields[i] = B_DATE_ELEMENT_INVALID; - break; - } - } - - return B_OK; -} - - -status_t -BCountry::SetTimeFormat(const char* formatString, bool longFormat) -{ - if (longFormat) - fLongTimeFormat = formatString; - else - fShortTimeFormat = formatString; - - return B_OK; -} - - -status_t -BCountry::GetTimeFormat(BString& format, bool longFormat) const -{ - if (longFormat && fLongTimeFormat.Length() > 0) - format = fLongTimeFormat; - else if (!longFormat && fShortTimeFormat.Length() > 0) - format = fShortTimeFormat; - else { - format.Truncate(0); - - ObjectDeleter timeFormatter = CreateTimeFormat(longFormat, - *fICULocale, longFormat ? fLongTimeFormat : fShortTimeFormat); - if (timeFormatter.Get() == NULL) - return B_NO_MEMORY; - - SimpleDateFormat* timeFormatterImpl - = static_cast(timeFormatter.Get()); - - UnicodeString ICUString; - ICUString = timeFormatterImpl->toPattern(ICUString); - - BStringByteSink stringConverter(&format); - ICUString.toUTF8(stringConverter); - } - - return B_OK; -} - - -// #pragma mark - Numbers - - -status_t -BCountry::FormatNumber(char* string, size_t maxSize, double value) -{ - BString fullString; - status_t status = FormatNumber(&fullString, value); - if (status == B_OK) - strlcpy(string, fullString.String(), maxSize); - - return status; -} - - -status_t -BCountry::FormatNumber(BString* string, double value) -{ - UErrorCode err = U_ZERO_ERROR; - ObjectDeleter numberFormatter = NumberFormat::createInstance( - *fICULocale, NumberFormat::kNumberStyle, err); - - if (numberFormatter.Get() == NULL) - return B_NO_MEMORY; - if (U_FAILURE(err)) - return B_ERROR; - - UnicodeString ICUString; - ICUString = numberFormatter->format(value, ICUString); - - string->Truncate(0); - BStringByteSink stringConverter(string); - ICUString.toUTF8(stringConverter); - - return B_OK; -} - - -status_t -BCountry::FormatNumber(char* string, size_t maxSize, int32 value) -{ - BString fullString; - status_t status = FormatNumber(&fullString, value); - if (status == B_OK) - strlcpy(string, fullString.String(), maxSize); - - return status; -} - - -status_t -BCountry::FormatNumber(BString* string, int32 value) -{ - UErrorCode err = U_ZERO_ERROR; - ObjectDeleter numberFormatter = NumberFormat::createInstance( - *fICULocale, NumberFormat::kNumberStyle, err); - - if (numberFormatter.Get() == NULL) - return B_NO_MEMORY; - if (U_FAILURE(err)) - return B_ERROR; - - UnicodeString ICUString; - ICUString = numberFormatter->format((int32_t)value, ICUString); - - string->Truncate(0); - BStringByteSink stringConverter(string); - ICUString.toUTF8(stringConverter); - - return B_OK; -} - - // TODO does ICU even support this ? Is it in the keywords ? int8 BCountry::Measurement() const @@ -615,44 +128,6 @@ BCountry::Measurement() const } -ssize_t -BCountry::FormatMonetary(char* string, size_t maxSize, double value) -{ - BString fullString; - ssize_t written = FormatMonetary(&fullString, value); - if (written < 0) - return written; - - return strlcpy(string, fullString.String(), maxSize); -} - - -ssize_t -BCountry::FormatMonetary(BString* string, double value) -{ - if (string == NULL) - return B_BAD_VALUE; - - UErrorCode err; - ObjectDeleter numberFormatter - = NumberFormat::createCurrencyInstance(*fICULocale, err); - - if (numberFormatter.Get() == NULL) - return B_NO_MEMORY; - if (U_FAILURE(err)) - return B_ERROR; - - UnicodeString ICUString; - ICUString = numberFormatter->format(value, ICUString); - - string->Truncate(0); - BStringByteSink stringConverter(string); - ICUString.toUTF8(stringConverter); - - return string->Length(); -} - - // #pragma mark - Timezones @@ -687,42 +162,3 @@ BCountry::GetTimeZones(BList& timezones) const } -// #pragma mark - Helpers - - -static DateFormat* -CreateDateFormat(bool longFormat, const Locale& locale, - const BString& format) -{ - DateFormat* dateFormatter = DateFormat::createDateInstance( - longFormat ? DateFormat::FULL : DateFormat::SHORT, locale); - - if (format.Length() > 0) { - SimpleDateFormat* dateFormatterImpl - = static_cast(dateFormatter); - - UnicodeString pattern(format.String()); - dateFormatterImpl->applyPattern(pattern); - } - - return dateFormatter; -} - - -static DateFormat* -CreateTimeFormat(bool longFormat, const Locale& locale, - const BString& format) -{ - DateFormat* timeFormatter = DateFormat::createTimeInstance( - longFormat ? DateFormat::MEDIUM : DateFormat::SHORT, locale); - - if (format.Length() > 0) { - SimpleDateFormat* timeFormatterImpl - = static_cast(timeFormatter); - - UnicodeString pattern(format.String()); - timeFormatterImpl->applyPattern(pattern); - } - - return timeFormatter; -} diff --git a/src/kits/locale/Jamfile b/src/kits/locale/Jamfile index a6c2826a20..893906e204 100644 --- a/src/kits/locale/Jamfile +++ b/src/kits/locale/Jamfile @@ -40,7 +40,6 @@ local sources = IntegerFormat.cpp IntegerFormatImpl.cpp IntegerFormatParameters.cpp - langinfo.cpp NumberFormat.cpp NumberFormatImpl.cpp NumberFormatParameters.cpp diff --git a/src/kits/locale/Locale.cpp b/src/kits/locale/Locale.cpp index 3d680cab30..98c74e879f 100644 --- a/src/kits/locale/Locale.cpp +++ b/src/kits/locale/Locale.cpp @@ -4,26 +4,81 @@ */ +#include +#include #include #include #include +#include +#include +#include +#include +#include +#include -static BLocale gLocale; -BLocale *be_locale = &gLocale; +#include -BLocale::BLocale() +#define ICU_VERSION icu_44 + + +using BPrivate::ObjectDeleter; +using BPrivate::B_WEEK_START_MONDAY; +using BPrivate::B_WEEK_START_SUNDAY; + + +static DateFormat* CreateDateFormat(bool longFormat, const Locale& locale, + const BString& format); +static DateFormat* CreateTimeFormat(bool longFormat, const Locale& locale, + const BString& format); + + +BLocale::BLocale(const char* languageAndCountryCode) + : + fCountry(languageAndCountryCode), + fLanguage(languageAndCountryCode), + fICULocale(new ICU_VERSION::Locale(languageAndCountryCode)) { - BLocaleRoster roster; - roster.GetDefaultCollator(&fCollator); - roster.GetDefaultCountry(&fCountry); - roster.GetDefaultLanguage(&fLanguage); +} + + +BLocale::BLocale(const BLocale& other) + : + fCountry(other.fCountry), + fLanguage(other.fLanguage), + fICULocale(new ICU_VERSION::Locale(*other.fICULocale)), + fLongDateFormat(other.fLongDateFormat), + fShortDateFormat(other.fShortDateFormat), + fLongTimeFormat(other.fLongTimeFormat), + fShortTimeFormat(other.fShortTimeFormat) +{ +} + + +BLocale& +BLocale::operator=(const BLocale& other) +{ + if (this == &other) + return *this; + + *fICULocale = *other.fICULocale; + + fLongDateFormat = other.fLongDateFormat; + fShortDateFormat = other.fShortDateFormat; + fLongTimeFormat = other.fLongTimeFormat; + fShortTimeFormat = other.fShortTimeFormat; + + fCountry = other.fCountry; + fLanguage = other.fLanguage; + + return *this; } BLocale::~BLocale() { + delete fICULocale; } @@ -40,3 +95,571 @@ BLocale::GetString(uint32 id) } return fLanguage.GetString(id); } + + +void +BLocale::SetCountry(const BCountry& newCountry) +{ + fCountry = newCountry; +} + + +void +BLocale::SetCollator(const BCollator& newCollator) +{ + fCollator = newCollator; +} + + +void +BLocale::SetLanguage(const char* languageCode) +{ + fLanguage.SetTo(languageCode); +} + + +const char* +BLocale::Code() const +{ + return fICULocale->getName(); +} + + +// #pragma mark - Date + + +status_t +BLocale::FormatDate(char* string, size_t maxSize, time_t time, bool longFormat) +{ + ObjectDeleter dateFormatter = CreateDateFormat(longFormat, + *fICULocale, longFormat ? fLongDateFormat : fShortDateFormat); + if (dateFormatter.Get() == NULL) + return B_NO_MEMORY; + + UnicodeString ICUString; + ICUString = dateFormatter->format((UDate)time * 1000, ICUString); + + CheckedArrayByteSink stringConverter(string, maxSize); + + ICUString.toUTF8(stringConverter); + + if (stringConverter.Overflowed()) + return B_BAD_VALUE; + + return B_OK; +} + + +status_t +BLocale::FormatDate(BString *string, time_t time, bool longFormat) +{ + string->Truncate(0); + // We make the string empty, this way even in cases where ICU fail we at + // least return something sane + ObjectDeleter dateFormatter = CreateDateFormat(longFormat, + *fICULocale, longFormat ? fLongDateFormat : fShortDateFormat); + if (dateFormatter.Get() == NULL) + return B_NO_MEMORY; + + UnicodeString ICUString; + ICUString = dateFormatter->format((UDate)time * 1000, ICUString); + + BStringByteSink stringConverter(string); + + ICUString.toUTF8(stringConverter); + + return B_OK; +} + + +status_t +BLocale::FormatDate(BString* string, int*& fieldPositions, int& fieldCount, + time_t time, bool longFormat) +{ + string->Truncate(0); + + ObjectDeleter dateFormatter = CreateDateFormat(longFormat, + *fICULocale, longFormat ? fLongDateFormat : fShortDateFormat); + if (dateFormatter.Get() == NULL) + return B_NO_MEMORY; + + fieldPositions = NULL; + UErrorCode error = U_ZERO_ERROR; + ICU_VERSION::FieldPositionIterator positionIterator; + UnicodeString ICUString; + ICUString = dateFormatter->format((UDate)time * 1000, ICUString, + &positionIterator, error); + + if (error != U_ZERO_ERROR) + return B_ERROR; + + ICU_VERSION::FieldPosition field; + std::vector fieldPosStorage; + fieldCount = 0; + while (positionIterator.next(field)) { + fieldPosStorage.push_back(field.getBeginIndex()); + fieldPosStorage.push_back(field.getEndIndex()); + fieldCount += 2; + } + + fieldPositions = (int*) malloc(fieldCount * sizeof(int)); + + for (int i = 0 ; i < fieldCount ; i++ ) + fieldPositions[i] = fieldPosStorage[i]; + + BStringByteSink stringConverter(string); + + ICUString.toUTF8(stringConverter); + + return B_OK; +} + + +status_t +BLocale::GetDateFormat(BString& format, bool longFormat) const +{ + if (longFormat && fLongDateFormat.Length() > 0) + format = fLongDateFormat; + else if (!longFormat && fShortDateFormat.Length() > 0) + format = fShortDateFormat; + else { + format.Truncate(0); + + ObjectDeleter dateFormatter = CreateDateFormat(longFormat, + *fICULocale, longFormat ? fLongDateFormat : fShortDateFormat); + if (dateFormatter.Get() == NULL) + return B_NO_MEMORY; + + SimpleDateFormat* dateFormatterImpl + = static_cast(dateFormatter.Get()); + + UnicodeString ICUString; + ICUString = dateFormatterImpl->toPattern(ICUString); + + BStringByteSink stringConverter(&format); + + ICUString.toUTF8(stringConverter); + } + + return B_OK; +} + + +status_t +BLocale::SetDateFormat(const char* formatString, bool longFormat) +{ +printf("FV::SetDateFormat: df='%s'\n", formatString); + if (longFormat) + fLongDateFormat = formatString; + else + fShortDateFormat = formatString; + + return B_OK; +} + + +status_t +BLocale::GetDateFields(BDateElement*& fields, int& fieldCount, + bool longFormat) const +{ + ObjectDeleter dateFormatter = CreateDateFormat(longFormat, + *fICULocale, longFormat ? fLongDateFormat : fShortDateFormat); + if (dateFormatter.Get() == NULL) + return B_NO_MEMORY; + + fields = NULL; + UErrorCode error = U_ZERO_ERROR; + ICU_VERSION::FieldPositionIterator positionIterator; + UnicodeString ICUString; + time_t now; + ICUString = dateFormatter->format((UDate)time(&now) * 1000, ICUString, + &positionIterator, error); + + if (U_FAILURE(error)) + return B_ERROR; + + ICU_VERSION::FieldPosition field; + std::vector fieldPosStorage; + fieldCount = 0; + while (positionIterator.next(field)) { + fieldPosStorage.push_back(field.getField()); + fieldCount ++; + } + + fields = (BDateElement*) malloc(fieldCount * sizeof(BDateElement)); + + for (int i = 0 ; i < fieldCount ; i++ ) { + switch (fieldPosStorage[i]) { + case UDAT_YEAR_FIELD: + fields[i] = B_DATE_ELEMENT_YEAR; + break; + case UDAT_MONTH_FIELD: + fields[i] = B_DATE_ELEMENT_MONTH; + break; + case UDAT_DATE_FIELD: + fields[i] = B_DATE_ELEMENT_DAY; + break; + default: + fields[i] = B_DATE_ELEMENT_INVALID; + break; + } + } + + return B_OK; +} + + +int +BLocale::StartOfWeek() const +{ + UErrorCode err = U_ZERO_ERROR; + Calendar* c = Calendar::createInstance(*fICULocale, err); + + if (err == U_ZERO_ERROR && c->getFirstDayOfWeek(err) == UCAL_SUNDAY) { + delete c; + return B_WEEK_START_SUNDAY; + } else { + delete c; + // Might be another day, but BeAPI will not handle it + return B_WEEK_START_MONDAY; + } +} + + +// #pragma mark - Time + + +status_t +BLocale::FormatTime(char* string, size_t maxSize, time_t time, bool longFormat) +{ + ObjectDeleter timeFormatter = CreateTimeFormat(longFormat, + *fICULocale, longFormat ? fLongTimeFormat : fShortTimeFormat); + if (timeFormatter.Get() == NULL) + return B_NO_MEMORY; + + UnicodeString ICUString; + ICUString = timeFormatter->format((UDate)time * 1000, ICUString); + + CheckedArrayByteSink stringConverter(string, maxSize); + + ICUString.toUTF8(stringConverter); + + if (stringConverter.Overflowed()) + return B_BAD_VALUE; + + return B_OK; +} + + +status_t +BLocale::FormatTime(BString* string, time_t time, bool longFormat) +{ + string->Truncate(0); + + ObjectDeleter timeFormatter = CreateTimeFormat(longFormat, + *fICULocale, longFormat ? fLongTimeFormat : fShortTimeFormat); + if (timeFormatter.Get() == NULL) + return B_NO_MEMORY; + + UnicodeString ICUString; + ICUString = timeFormatter->format((UDate)time * 1000, ICUString); + + BStringByteSink stringConverter(string); + + ICUString.toUTF8(stringConverter); + + return B_OK; +} + + +status_t +BLocale::FormatTime(BString* string, int*& fieldPositions, int& fieldCount, + time_t time, bool longFormat) +{ + string->Truncate(0); + + ObjectDeleter timeFormatter = CreateTimeFormat(longFormat, + *fICULocale, longFormat ? fLongTimeFormat : fShortTimeFormat); + if (timeFormatter.Get() == NULL) + return B_NO_MEMORY; + + fieldPositions = NULL; + UErrorCode error = U_ZERO_ERROR; + ICU_VERSION::FieldPositionIterator positionIterator; + UnicodeString ICUString; + ICUString = timeFormatter->format((UDate)time * 1000, ICUString, + &positionIterator, error); + + if (error != U_ZERO_ERROR) + return B_ERROR; + + ICU_VERSION::FieldPosition field; + std::vector fieldPosStorage; + fieldCount = 0; + while (positionIterator.next(field)) { + fieldPosStorage.push_back(field.getBeginIndex()); + fieldPosStorage.push_back(field.getEndIndex()); + fieldCount += 2; + } + + fieldPositions = (int*) malloc(fieldCount * sizeof(int)); + + for (int i = 0 ; i < fieldCount ; i++ ) + fieldPositions[i] = fieldPosStorage[i]; + + BStringByteSink stringConverter(string); + + ICUString.toUTF8(stringConverter); + + return B_OK; +} + + +status_t +BLocale::GetTimeFields(BDateElement*& fields, int& fieldCount, + bool longFormat) const +{ + ObjectDeleter timeFormatter = CreateTimeFormat(longFormat, + *fICULocale, longFormat ? fLongTimeFormat : fShortTimeFormat); + if (timeFormatter.Get() == NULL) + return B_NO_MEMORY; + + fields = NULL; + UErrorCode error = U_ZERO_ERROR; + ICU_VERSION::FieldPositionIterator positionIterator; + UnicodeString ICUString; + time_t now; + ICUString = timeFormatter->format((UDate)time(&now) * 1000, ICUString, + &positionIterator, error); + + if (error != U_ZERO_ERROR) + return B_ERROR; + + ICU_VERSION::FieldPosition field; + std::vector fieldPosStorage; + fieldCount = 0; + while (positionIterator.next(field)) { + fieldPosStorage.push_back(field.getField()); + fieldCount ++; + } + + fields = (BDateElement*) malloc(fieldCount * sizeof(BDateElement)); + + for (int i = 0 ; i < fieldCount ; i++ ) { + switch (fieldPosStorage[i]) { + case UDAT_HOUR_OF_DAY1_FIELD: + case UDAT_HOUR_OF_DAY0_FIELD: + case UDAT_HOUR1_FIELD: + case UDAT_HOUR0_FIELD: + fields[i] = B_DATE_ELEMENT_HOUR; + break; + case UDAT_MINUTE_FIELD: + fields[i] = B_DATE_ELEMENT_MINUTE; + break; + case UDAT_SECOND_FIELD: + fields[i] = B_DATE_ELEMENT_SECOND; + break; + case UDAT_AM_PM_FIELD: + fields[i] = B_DATE_ELEMENT_AM_PM; + break; + default: + fields[i] = B_DATE_ELEMENT_INVALID; + break; + } + } + + return B_OK; +} + + +status_t +BLocale::SetTimeFormat(const char* formatString, bool longFormat) +{ + if (longFormat) + fLongTimeFormat = formatString; + else + fShortTimeFormat = formatString; + + return B_OK; +} + + +status_t +BLocale::GetTimeFormat(BString& format, bool longFormat) const +{ + if (longFormat && fLongTimeFormat.Length() > 0) + format = fLongTimeFormat; + else if (!longFormat && fShortTimeFormat.Length() > 0) + format = fShortTimeFormat; + else { + format.Truncate(0); + + ObjectDeleter timeFormatter = CreateTimeFormat(longFormat, + *fICULocale, longFormat ? fLongTimeFormat : fShortTimeFormat); + if (timeFormatter.Get() == NULL) + return B_NO_MEMORY; + + SimpleDateFormat* timeFormatterImpl + = static_cast(timeFormatter.Get()); + + UnicodeString ICUString; + ICUString = timeFormatterImpl->toPattern(ICUString); + + BStringByteSink stringConverter(&format); + ICUString.toUTF8(stringConverter); + } + + return B_OK; +} + + +// #pragma mark - Numbers + + +status_t +BLocale::FormatNumber(char* string, size_t maxSize, double value) +{ + BString fullString; + status_t status = FormatNumber(&fullString, value); + if (status == B_OK) + strlcpy(string, fullString.String(), maxSize); + + return status; +} + + +status_t +BLocale::FormatNumber(BString* string, double value) +{ + UErrorCode err = U_ZERO_ERROR; + ObjectDeleter numberFormatter = NumberFormat::createInstance( + *fICULocale, NumberFormat::kNumberStyle, err); + + if (numberFormatter.Get() == NULL) + return B_NO_MEMORY; + if (U_FAILURE(err)) + return B_ERROR; + + UnicodeString ICUString; + ICUString = numberFormatter->format(value, ICUString); + + string->Truncate(0); + BStringByteSink stringConverter(string); + ICUString.toUTF8(stringConverter); + + return B_OK; +} + + +status_t +BLocale::FormatNumber(char* string, size_t maxSize, int32 value) +{ + BString fullString; + status_t status = FormatNumber(&fullString, value); + if (status == B_OK) + strlcpy(string, fullString.String(), maxSize); + + return status; +} + + +status_t +BLocale::FormatNumber(BString* string, int32 value) +{ + UErrorCode err = U_ZERO_ERROR; + ObjectDeleter numberFormatter = NumberFormat::createInstance( + *fICULocale, NumberFormat::kNumberStyle, err); + + if (numberFormatter.Get() == NULL) + return B_NO_MEMORY; + if (U_FAILURE(err)) + return B_ERROR; + + UnicodeString ICUString; + ICUString = numberFormatter->format((int32_t)value, ICUString); + + string->Truncate(0); + BStringByteSink stringConverter(string); + ICUString.toUTF8(stringConverter); + + return B_OK; +} + + +ssize_t +BLocale::FormatMonetary(char* string, size_t maxSize, double value) +{ + BString fullString; + ssize_t written = FormatMonetary(&fullString, value); + if (written < 0) + return written; + + return strlcpy(string, fullString.String(), maxSize); +} + + +ssize_t +BLocale::FormatMonetary(BString* string, double value) +{ + if (string == NULL) + return B_BAD_VALUE; + + UErrorCode err; + ObjectDeleter numberFormatter + = NumberFormat::createCurrencyInstance(*fICULocale, err); + + if (numberFormatter.Get() == NULL) + return B_NO_MEMORY; + if (U_FAILURE(err)) + return B_ERROR; + + UnicodeString ICUString; + ICUString = numberFormatter->format(value, ICUString); + + string->Truncate(0); + BStringByteSink stringConverter(string); + ICUString.toUTF8(stringConverter); + + return string->Length(); +} + + +// #pragma mark - Helpers + + +static DateFormat* +CreateDateFormat(bool longFormat, const Locale& locale, + const BString& format) +{ + DateFormat* dateFormatter = DateFormat::createDateInstance( + longFormat ? DateFormat::FULL : DateFormat::SHORT, locale); + + if (format.Length() > 0) { + SimpleDateFormat* dateFormatterImpl + = static_cast(dateFormatter); + + UnicodeString pattern(format.String()); + dateFormatterImpl->applyPattern(pattern); + } + + return dateFormatter; +} + + +static DateFormat* +CreateTimeFormat(bool longFormat, const Locale& locale, + const BString& format) +{ + DateFormat* timeFormatter = DateFormat::createTimeInstance( + longFormat ? DateFormat::MEDIUM : DateFormat::SHORT, locale); + + if (format.Length() > 0) { + SimpleDateFormat* timeFormatterImpl + = static_cast(timeFormatter); + + UnicodeString pattern(format.String()); + timeFormatterImpl->applyPattern(pattern); + } + + return timeFormatter; +} diff --git a/src/kits/locale/LocaleRoster.cpp b/src/kits/locale/LocaleRoster.cpp index e15b0e4abe..7da6475e16 100644 --- a/src/kits/locale/LocaleRoster.cpp +++ b/src/kits/locale/LocaleRoster.cpp @@ -88,7 +88,7 @@ BLocaleRoster::GetDefaultCollator(BCollator* collator) const if (!lock.IsLocked()) return B_ERROR; - *collator = gRosterData.fDefaultCollator; + *collator = *gRosterData.fDefaultLocale.Collator(); return B_OK; } @@ -104,7 +104,7 @@ BLocaleRoster::GetDefaultLanguage(BLanguage* language) const if (!lock.IsLocked()) return B_ERROR; - *language = gRosterData.fDefaultLanguage; + *language = *gRosterData.fDefaultLocale.Language(); return B_OK; } @@ -120,7 +120,23 @@ BLocaleRoster::GetDefaultCountry(BCountry* country) const if (!lock.IsLocked()) return B_ERROR; - *country = gRosterData.fDefaultCountry; + *country = *gRosterData.fDefaultLocale.Country(); + + return B_OK; +} + + +status_t +BLocaleRoster::GetDefaultLocale(BLocale* locale) const +{ + if (!locale) + return B_BAD_VALUE; + + BAutolock lock(gRosterData.fLock); + if (!lock.IsLocked()) + return B_ERROR; + + *locale = gRosterData.fDefaultLocale; return B_OK; } diff --git a/src/kits/locale/MutableLocaleRoster.cpp b/src/kits/locale/MutableLocaleRoster.cpp index 5a640b05cd..598b7f1549 100644 --- a/src/kits/locale/MutableLocaleRoster.cpp +++ b/src/kits/locale/MutableLocaleRoster.cpp @@ -346,6 +346,32 @@ RosterData::SetDefaultCountry(const BCountry& newCountry) } +status_t +RosterData::SetDefaultLocale(const BLocale& newLocale) +{ + status_t status = B_OK; + + BAutolock lock(fLock); + if (!lock.IsLocked()) + return B_ERROR; + + status = _SetDefaultLocale(newLocale); + + if (status == B_OK) + status = _SaveLocaleSettings(); + + if (status == B_OK) { + BMessage updateMessage(B_LOCALE_CHANGED); + status = _AddDefaultCountryToMessage(&updateMessage); + // TODO : should be differenciated from country + if (status == B_OK) + status = be_roster->Broadcast(&updateMessage); + } + + return status; +} + + status_t RosterData::SetDefaultTimeZone(const BTimeZone& newZone) { @@ -414,18 +440,18 @@ RosterData::_LoadLocaleSettings() if (status == B_OK) { BString codeName; - BCountry newDefaultCountry; + BLocale newDefaultLocale; if (settings.FindString("country", &codeName) == B_OK) - newDefaultCountry = BCountry(codeName); + newDefaultLocale = BLocale(codeName); BString timeFormat; if (settings.FindString("shortTimeFormat", &timeFormat) == B_OK) - newDefaultCountry.SetTimeFormat(timeFormat, false); + newDefaultLocale.SetTimeFormat(timeFormat, false); if (settings.FindString("longTimeFormat", &timeFormat) == B_OK) - newDefaultCountry.SetTimeFormat(timeFormat, true); + newDefaultLocale.SetTimeFormat(timeFormat, true); - _SetDefaultCountry(newDefaultCountry); + _SetDefaultLocale(newDefaultLocale); return B_OK; } @@ -526,7 +552,16 @@ RosterData::_SaveTimeSettings() status_t RosterData::_SetDefaultCountry(const BCountry& newCountry) { - fDefaultCountry = newCountry; + fDefaultLocale.SetCountry(newCountry); + + return B_OK; +} + + +status_t +RosterData::_SetDefaultLocale(const BLocale& newLocale) +{ + fDefaultLocale = newLocale; return B_OK; } @@ -556,8 +591,8 @@ RosterData::_SetPreferredLanguages(const BMessage* languages) if (!U_SUCCESS(icuError)) return B_ERROR; - fDefaultCollator = BCollator(langName.String()); - fDefaultLanguage.SetTo(langName.String()); + fDefaultLocale.SetCollator(BCollator(langName.String())); + fDefaultLocale.SetLanguage(langName.String()); fPreferredLanguages.RemoveName("language"); for (int i = 0; languages->FindString("language", i, &langName) == B_OK; @@ -576,14 +611,14 @@ RosterData::_SetPreferredLanguages(const BMessage* languages) status_t RosterData::_AddDefaultCountryToMessage(BMessage* message) const { - status_t status = message->AddString("country", fDefaultCountry.Code()); + status_t status = message->AddString("country", fDefaultLocale.Code()); BString timeFormat; if (status == B_OK) - status = fDefaultCountry.GetTimeFormat(timeFormat, false); + status = fDefaultLocale.GetTimeFormat(timeFormat, false); if (status == B_OK) status = message->AddString("shortTimeFormat", timeFormat.String()); if (status == B_OK) - status = fDefaultCountry.GetTimeFormat(timeFormat, true); + status = fDefaultLocale.GetTimeFormat(timeFormat, true); if (status == B_OK) status = message->AddString("longTimeFormat", timeFormat.String()); @@ -646,6 +681,13 @@ MutableLocaleRoster::SetDefaultCountry(const BCountry& newCountry) } +status_t +MutableLocaleRoster::SetDefaultLocale(const BLocale& newLocale) +{ + return gRosterData.SetDefaultLocale(newLocale); +} + + status_t MutableLocaleRoster::SetDefaultTimeZone(const BTimeZone& newZone) { diff --git a/src/kits/locale/langinfo.cpp b/src/kits/locale/langinfo.cpp deleted file mode 100644 index f0f8cd21dd..0000000000 --- a/src/kits/locale/langinfo.cpp +++ /dev/null @@ -1,20 +0,0 @@ -/* -** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved. -** Distributed under the terms of the OpenBeOS License. -*/ - - -#include -#include - - -char * -nl_langinfo(nl_item id) -{ - if (be_locale != NULL) - be_locale->GetString(id); - - // ToDo: return default values! - return (char*)""; -} - diff --git a/src/preferences/locale/FormatSettingsView.cpp b/src/preferences/locale/FormatSettingsView.cpp index 6779b68835..5bcfebb903 100644 --- a/src/preferences/locale/FormatSettingsView.cpp +++ b/src/preferences/locale/FormatSettingsView.cpp @@ -148,10 +148,10 @@ IsSpecialDateChar(char charToTest) // #pragma mark - -FormatView::FormatView(const BCountry& country) +FormatView::FormatView(const BLocale& locale) : BView("WindowsSettingsView", B_FRAME_EVENTS), - fCountry(country) + fLocale(locale) { SetLayout(new BGroupLayout(B_HORIZONTAL)); @@ -189,14 +189,14 @@ FormatView::FormatView(const BCountry& country) f12HrRadioButton = new BRadioButton("", B_TRANSLATE("12 hour"), new BMessage(kClockFormatChange)); - fCountry.GetTimeFormat(fOriginalTimeFormat, false); - fCountry.GetTimeFormat(fOriginalLongTimeFormat, true); + fLocale.GetTimeFormat(fOriginalTimeFormat, false); + fLocale.GetTimeFormat(fOriginalLongTimeFormat, true); if (fOriginalTimeFormat.FindFirst("a") != B_ERROR) { f12HrRadioButton->SetValue(B_CONTROL_ON); - fCountryIs24Hr = false; + fLocaleIs24Hr = false; } else { f24HrRadioButton->SetValue(B_CONTROL_ON); - fCountryIs24Hr = true; + fLocaleIs24Hr = true; } float spacing = be_control_look->DefaultItemSpacing(); @@ -360,7 +360,7 @@ FormatView::FormatView(const BCountry& country) FormatView::~FormatView() { - mutable_locale_roster->SetDefaultCountry(fCountry); + mutable_locale_roster->SetDefaultLocale(fLocale); } @@ -433,17 +433,11 @@ FormatView::MessageReceived(BMessage* message) ; } - // TODO send that to our Settings class - // settings.SetDateOrderFormat(format); - // settings.SetClockTo24Hr(f24HrRadioButton->Value() == 1); - // Make the notification message and send it to the tracker: BMessage notificationMessage; notificationMessage.AddInt32("TimeFormatSeparator", separator); notificationMessage.AddBool("24HrClock", f24HrRadioButton->Value() == 1); - // tracker->SendNotices(kDateFormatChanged, - // ¬ificationMessage); _UpdateExamples(); @@ -458,38 +452,38 @@ FormatView::MessageReceived(BMessage* message) BString timeFormat; timeFormat = fOriginalTimeFormat; if (f24HrRadioButton->Value() == 1) { - if (!fCountryIs24Hr) { + if (!fLocaleIs24Hr) { timeFormat.ReplaceAll("h", "H"); timeFormat.ReplaceAll("k", "K"); timeFormat.RemoveAll(" a"); timeFormat.RemoveAll("a"); } } else { - if (fCountryIs24Hr && timeFormat.FindFirst("a") == B_ERROR) { + if (fLocaleIs24Hr && timeFormat.FindFirst("a") == B_ERROR) { timeFormat.ReplaceAll("K", "k"); timeFormat.ReplaceAll("H", "h"); timeFormat.Append(" a"); } } - fCountry.SetTimeFormat(timeFormat.String(), false); + fLocale.SetTimeFormat(timeFormat.String(), false); newMessage.AddString("shortTimeFormat", timeFormat); timeFormat = fOriginalLongTimeFormat; if (f24HrRadioButton->Value() == 1) { - if (!fCountryIs24Hr) { + if (!fLocaleIs24Hr) { timeFormat.ReplaceAll("h", "H"); timeFormat.ReplaceAll("k", "K"); timeFormat.RemoveAll(" a"); timeFormat.RemoveAll("a"); } } else { - if (fCountryIs24Hr && timeFormat.FindFirst("a") == B_ERROR) { + if (fLocaleIs24Hr && timeFormat.FindFirst("a") == B_ERROR) { timeFormat.ReplaceAll("K", "k"); timeFormat.ReplaceAll("H", "h"); timeFormat.Append(" a"); } } - fCountry.SetTimeFormat(timeFormat.String(), true); + fLocale.SetTimeFormat(timeFormat.String(), true); newMessage.AddString("longTimeFormat", timeFormat); _UpdateExamples(); Window()->PostMessage(kSettingsContentsModified); @@ -514,9 +508,9 @@ FormatView::SetDefaults() settings.SetClockTo24Hr(false); */ - BCountry defaultCountry; - be_locale_roster->GetDefaultCountry(&defaultCountry); - fCountry = defaultCountry; + BLocale defaultLocale; + be_locale_roster->GetDefaultLocale(&defaultLocale); + fLocale = defaultLocale; // We work on a copy of the default country and set the changes when // closing the preflet _UpdateExamples(); @@ -555,19 +549,19 @@ FormatView::Revert() void -FormatView::SetCountry(const BCountry& country) +FormatView::SetLocale(const BLocale& locale) { - fCountry = country; + fLocale = locale; - fCountry.GetTimeFormat(fOriginalTimeFormat, false); - fCountry.GetTimeFormat(fOriginalLongTimeFormat, true); + fLocale.GetTimeFormat(fOriginalTimeFormat, false); + fLocale.GetTimeFormat(fOriginalLongTimeFormat, true); if (fOriginalTimeFormat.FindFirst("a") != B_ERROR) { f12HrRadioButton->SetValue(B_CONTROL_ON); - fCountryIs24Hr = false; + fLocaleIs24Hr = false; } else { f24HrRadioButton->SetValue(B_CONTROL_ON); - fCountryIs24Hr = true; + fLocaleIs24Hr = true; } /* @@ -626,19 +620,19 @@ FormatView::_UpdateExamples() time_t timeValue = (time_t)time(NULL); BString timeFormat; - fCountry.FormatDate(&timeFormat, timeValue, true); + fLocale.FormatDate(&timeFormat, timeValue, true); fLongDateExampleView->SetText(timeFormat); - fCountry.FormatDate(&timeFormat, timeValue, false); + fLocale.FormatDate(&timeFormat, timeValue, false); fShortDateExampleView->SetText(timeFormat); - fCountry.FormatTime(&timeFormat, timeValue, true); + fLocale.FormatTime(&timeFormat, timeValue, true); fLongTimeExampleView->SetText(timeFormat); - fCountry.FormatTime(&timeFormat, timeValue, false); + fLocale.FormatTime(&timeFormat, timeValue, false); fShortTimeExampleView->SetText(timeFormat); - status_t Error = fCountry.FormatNumber(&timeFormat, 1234.5678); + status_t Error = fLocale.FormatNumber(&timeFormat, 1234.5678); if (Error == B_OK) fNumberFormatExampleView->SetText(timeFormat); else @@ -668,7 +662,7 @@ FormatView::_ParseDateFormat() { // TODO parse the short date too BString dateFormatString; - fCountry.GetDateFormat(dateFormatString, true); + fLocale.GetDateFormat(dateFormatString, true); const char* dateFormat = dateFormatString.String(); printf("FV::_ParseDateFormat: df='%s'\n", dateFormat); @@ -721,7 +715,7 @@ printf("FV::_ParseDateFormat: df='%s'\n", dateFormat); } // Short date is a bit more tricky, we want to extract the separator - fCountry.GetDateFormat(dateFormatString, false); + fLocale.GetDateFormat(dateFormatString, false); dateFormat = dateFormatString.String(); // Travel trough the string and parse it @@ -787,7 +781,7 @@ FormatView::_UpdateLongDateFormatString() } // TODO save this in the settings preflet and make the roster load it back - fCountry.SetDateFormat(newDateFormat.String()); + fLocale.SetDateFormat(newDateFormat.String()); newDateFormat.Truncate(0); @@ -798,5 +792,5 @@ FormatView::_UpdateLongDateFormatString() newDateFormat.Append(fDateString[2]); // TODO save this in the settings preflet and make the roster load it back - fCountry.SetDateFormat(newDateFormat.String(), false); + fLocale.SetDateFormat(newDateFormat.String(), false); } diff --git a/src/preferences/locale/FormatSettingsView.h b/src/preferences/locale/FormatSettingsView.h index 03a7bf9d84..55e4aa5bc3 100644 --- a/src/preferences/locale/FormatSettingsView.h +++ b/src/preferences/locale/FormatSettingsView.h @@ -7,7 +7,7 @@ #include -#include +#include #include #include @@ -37,7 +37,7 @@ const uint32 kMenuMessage = 'FRMT'; class FormatView : public BView { public: - FormatView(const BCountry& country); + FormatView(const BLocale& locale); ~FormatView(); virtual void MessageReceived(BMessage* message); @@ -46,7 +46,7 @@ public: virtual void SetDefaults(); virtual bool IsDefaultable() const; virtual void Revert(); - virtual void SetCountry(const BCountry& country); + virtual void SetLocale(const BLocale& locale); virtual void RecordRevertSettings(); virtual bool IsRevertable() const; @@ -81,9 +81,9 @@ private: BString fOriginalTimeFormat; BString fOriginalLongTimeFormat; - bool fCountryIs24Hr; + bool fLocaleIs24Hr; - BCountry fCountry; + BLocale fLocale; BBox* fDateBox; BBox* fTimeBox; diff --git a/src/preferences/locale/LocaleSettings.cpp b/src/preferences/locale/LocaleSettings.cpp index 8db0b2969b..7d978835ab 100644 --- a/src/preferences/locale/LocaleSettings.cpp +++ b/src/preferences/locale/LocaleSettings.cpp @@ -7,6 +7,7 @@ #include "LocaleSettings.h" #include +#include #include #include #include @@ -77,32 +78,32 @@ LocaleSettings::UpdateFrom(BMessage* message) mutable_locale_roster->SetPreferredLanguages(message); } - BCountry defaultCountry; - mutable_locale_roster->GetDefaultCountry(&defaultCountry); + BLocale defaultLocale; + mutable_locale_roster->GetDefaultLocale(&defaultLocale); bool countryChanged = false; if (message->FindString("country", &messageContent) == B_OK) { fMessage.ReplaceString("country", messageContent); fMessage.RemoveName("shortTimeFormat"); fMessage.RemoveName("longTimeFormat"); - defaultCountry = BCountry(messageContent.String()); + defaultLocale = BLocale(messageContent.String()); countryChanged = true; } if (message->FindString("shortTimeFormat", &messageContent) == B_OK) { fMessage.RemoveName("shortTimeFormat"); fMessage.AddString("shortTimeFormat", messageContent); - defaultCountry.SetTimeFormat(messageContent, false); + defaultLocale.SetTimeFormat(messageContent, false); countryChanged = true; } if (message->FindString("longTimeFormat", &messageContent) == B_OK) { fMessage.RemoveName("longTimeFormat"); fMessage.AddString("longTimeFormat", messageContent); - defaultCountry.SetTimeFormat(messageContent, true); + defaultLocale.SetTimeFormat(messageContent, true); countryChanged = true; } if (countryChanged) - mutable_locale_roster->SetDefaultCountry(defaultCountry); + mutable_locale_roster->SetDefaultLocale(defaultLocale); } diff --git a/src/preferences/locale/LocaleWindow.cpp b/src/preferences/locale/LocaleWindow.cpp index 6b96efdf7c..c19b889fef 100644 --- a/src/preferences/locale/LocaleWindow.cpp +++ b/src/preferences/locale/LocaleWindow.cpp @@ -76,8 +76,8 @@ LocaleWindow::LocaleWindow() BWindow(BRect(0, 0, 0, 0), "Locale", B_TITLED_WINDOW, B_QUIT_ON_WINDOW_CLOSE | B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS) { - BCountry defaultCountry; - be_locale_roster->GetDefaultCountry(&defaultCountry); + BLocale defaultLocale; + be_locale_roster->GetDefaultLocale(&defaultLocale); SetLayout(new BGroupLayout(B_HORIZONTAL)); @@ -199,7 +199,7 @@ LocaleWindow::LocaleWindow() = new LanguageListItem(countryName, countryCode, NULL); listView->AddItem(item); - if (!strcmp(countryCode, defaultCountry.Code())) + if (!strcmp(countryCode, defaultLocale.Code())) currentItem = item; } @@ -211,7 +211,7 @@ LocaleWindow::LocaleWindow() listView->SetExplicitMinSize( BSize(25 * be_plain_font->Size(), B_SIZE_UNSET)); - fFormatView = new FormatView(defaultCountry); + fFormatView = new FormatView(defaultLocale); countryTab->AddChild(BLayoutBuilder::Group<>(B_HORIZONTAL, spacing) .AddGroup(B_VERTICAL, 3) @@ -360,8 +360,8 @@ LocaleWindow::MessageReceived(BMessage* message) be_app_messenger.SendMessage(&newMessage); SettingsChanged(); - BCountry country(item->ID()); - fFormatView->SetCountry(country); + BLocale locale(item->ID()); + fFormatView->SetLocale(locale); break; } diff --git a/src/preferences/time/DateTimeEdit.cpp b/src/preferences/time/DateTimeEdit.cpp index b2b9691b45..a373779843 100644 --- a/src/preferences/time/DateTimeEdit.cpp +++ b/src/preferences/time/DateTimeEdit.cpp @@ -105,9 +105,9 @@ TTimeEdit::DrawSection(uint32 index, bool hasFocus) int* fieldPositions; int fieldCount; - BCountry country; - be_locale_roster->GetDefaultCountry(&country); - country.FormatTime(&text, fieldPositions, fieldCount, time, true); + BLocale locale; + be_locale_roster->GetDefaultLocale(&locale); + locale.FormatTime(&text, fieldPositions, fieldCount, time, true); // TODO : this should be cached somehow to not redo it for each field if (index * 2 + 1 > (uint32)fieldCount) { @@ -148,10 +148,10 @@ TTimeEdit::DrawSeparator(uint32 index) int* fieldPositions; int fieldCount; - BCountry country; - be_locale_roster->GetDefaultCountry(&country); + BLocale locale; + be_locale_roster->GetDefaultLocale(&locale); time_t time = fTime.Time_t(); - country.FormatTime(&text, fieldPositions, fieldCount, time, true); + locale.FormatTime(&text, fieldPositions, fieldCount, time, true); // TODO : this should be cached somehow to not redo it for each field if (index * 2 + 2 > (uint32)fieldCount) { @@ -265,8 +265,8 @@ TTimeEdit::BuildDispatch(BMessage* message) BDateElement* dateFormat; int fieldCount; - BCountry here; - be_locale_roster->GetDefaultCountry(&here); + BLocale here; + be_locale_roster->GetDefaultLocale(&here); here.GetTimeFields(dateFormat, fieldCount, true); if (fFocus > fieldCount) { free(dateFormat); @@ -303,8 +303,8 @@ TTimeEdit::_CheckRange() int32 value = fHoldValue; BDateElement* fields; int fieldCount; - BCountry here; - be_locale_roster->GetDefaultCountry(&here); + BLocale here; + be_locale_roster->GetDefaultLocale(&here); here.GetTimeFields(fields, fieldCount, true); if (fFocus > fieldCount) { free(fields); @@ -373,8 +373,8 @@ TTimeEdit::_IsValidDoubleDigi(int32 value) bool isInRange = false; BDateElement* fields; int fieldCount; - BCountry here; - be_locale_roster->GetDefaultCountry(&here); + BLocale here; + be_locale_roster->GetDefaultLocale(&here); here.GetTimeFields(fields, fieldCount, true); if (fFocus > fieldCount) { free(fields); @@ -412,8 +412,8 @@ TTimeEdit::_SectionValue(int32 index) const int32 value; BDateElement* fields; int fieldCount; - BCountry here; - be_locale_roster->GetDefaultCountry(&here); + BLocale here; + be_locale_roster->GetDefaultLocale(&here); here.GetTimeFields(fields, fieldCount, true); if (index > fieldCount) { free(fields); @@ -487,8 +487,8 @@ TDateEdit::KeyDown(const char* bytes, int32 numBytes) BDateElement* dateFormat; int fieldCount; - BCountry here; - be_locale_roster->GetDefaultCountry(&here); + BLocale here; + be_locale_roster->GetDefaultLocale(&here); here.GetDateFields(dateFormat, fieldCount, false); if (dateFormat[section] == B_DATE_ELEMENT_YEAR) { @@ -541,9 +541,9 @@ TDateEdit::DrawSection(uint32 index, bool hasFocus) int* fieldPositions; int fieldCount; - BCountry country; - be_locale_roster->GetDefaultCountry(&country); - country.FormatDate(&text, fieldPositions, fieldCount, dateTime.Time_t(), + BLocale locale; + be_locale_roster->GetDefaultLocale(&locale); + locale.FormatDate(&text, fieldPositions, fieldCount, dateTime.Time_t(), false); // TODO : this should be cached somehow to not redo it for each field @@ -587,10 +587,10 @@ TDateEdit::DrawSeparator(uint32 index) int* fieldPositions; int fieldCount; - BCountry country; - be_locale_roster->GetDefaultCountry(&country); + BLocale locale; + be_locale_roster->GetDefaultLocale(&locale); BDateTime dateTime(fDate, BTime()); - country.FormatDate(&text, fieldPositions, fieldCount, dateTime.Time_t(), + locale.FormatDate(&text, fieldPositions, fieldCount, dateTime.Time_t(), false); // TODO : this should be cached somehow to not redo it for each field @@ -716,8 +716,8 @@ TDateEdit::BuildDispatch(BMessage* message) BDateElement* dateFormat; int fieldCount; - BCountry here; - be_locale_roster->GetDefaultCountry(&here); + BLocale here; + be_locale_roster->GetDefaultLocale(&here); here.GetDateFields(dateFormat, fieldCount, false); if (fFocus > fieldCount) { free(dateFormat); @@ -754,8 +754,8 @@ TDateEdit::_CheckRange() int32 value = fHoldValue; BDateElement* fields; int fieldCount; - BCountry here; - be_locale_roster->GetDefaultCountry(&here); + BLocale here; + be_locale_roster->GetDefaultLocale(&here); here.GetDateFields(fields, fieldCount, false); if (fFocus > fieldCount) { free(fields); @@ -811,8 +811,8 @@ TDateEdit::_IsValidDoubleDigi(int32 value) bool isInRange = false; BDateElement* fields; int fieldCount; - BCountry here; - be_locale_roster->GetDefaultCountry(&here); + BLocale here; + be_locale_roster->GetDefaultLocale(&here); here.GetDateFields(fields, fieldCount, false); if (fFocus > fieldCount) { free(fields); @@ -852,8 +852,8 @@ TDateEdit::_SectionValue(int32 index) const int32 value = 0; BDateElement* fields; int fieldCount; - BCountry here; - be_locale_roster->GetDefaultCountry(&here); + BLocale here; + be_locale_roster->GetDefaultLocale(&here); here.GetDateFields(fields, fieldCount, false); if (index > fieldCount) { free(fields); diff --git a/src/preferences/time/ZoneView.cpp b/src/preferences/time/ZoneView.cpp index a2a87cf12a..6baa791224 100644 --- a/src/preferences/time/ZoneView.cpp +++ b/src/preferences/time/ZoneView.cpp @@ -374,7 +374,9 @@ TimeZoneView::_FormatTime(TimeZoneListItem* zoneItem) return result; time_t nowInTimeZone = time(NULL) + zoneItem->OffsetFromGMT(); - be_locale->FormatTime(&result, nowInTimeZone, false); + BLocale locale; + be_locale_roster->GetDefaultLocale(&locale); + locale.FormatTime(&result, nowInTimeZone, false); return result; }