* Move the locale-related stuff away from BCountry to BLocale.

* Remove the be_locale global object and go through the be_locale_roster instead
 * Rework the storage of data for the be_locale_roster, since BLocale already holds a BCountry and a BLanguage.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@37907 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Adrien Destugues
2010-08-04 18:45:06 +00:00
parent afbbc97abf
commit 5c3a303486
21 changed files with 870 additions and 808 deletions
-53
View File
@@ -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;
};
+62 -44
View File
@@ -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
+1
View File
@@ -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,
+5 -3
View File
@@ -11,6 +11,7 @@
#include <image.h>
#include <Language.h>
#include <List.h>
#include <Locale.h>
#include <Locker.h>
#include <LocaleRoster.h>
#include <Message.h>
@@ -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);
+3 -2
View File
@@ -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());
}
+3 -3
View File
@@ -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));
+5 -5
View File
@@ -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();
+2 -2
View File
@@ -36,7 +36,7 @@ All rights reserved.
#include <OS.h>
#include <Country.h>
#include <Locale.h>
#include <Messenger.h>
#include <View.h>
@@ -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
};
+2 -2
View File
@@ -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);
+3 -567
View File
@@ -8,7 +8,6 @@
#include <Country.h>
#include <AutoDeleter.h>
#include <CalendarView.h>
#include <IconUtils.h>
#include <List.h>
#include <Resources.h>
@@ -16,10 +15,7 @@
#include <TimeZone.h>
#include <unicode/datefmt.h>
#include <unicode/dcfmtsym.h>
#include <unicode/decimfmt.h>
#include <unicode/dtfmtsym.h>
#include <unicode/smpdtfmt.h>
#include <unicode/locid.h>
#include <ICUWrapper.h>
#include <iostream>
@@ -28,23 +24,11 @@
#include <new>
#include <stdarg.h>
#include <stdlib.h>
#include <vector>
#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<DateFormat> 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<DateFormat> 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<DateFormat> 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<int> 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<DateFormat> dateFormatter = CreateDateFormat(longFormat,
*fICULocale, longFormat ? fLongDateFormat : fShortDateFormat);
if (dateFormatter.Get() == NULL)
return B_NO_MEMORY;
SimpleDateFormat* dateFormatterImpl
= static_cast<SimpleDateFormat*>(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<DateFormat> 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<int> 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<DateFormat> 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<DateFormat> 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<DateFormat> 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<int> 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<DateFormat> 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<int> 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<DateFormat> timeFormatter = CreateTimeFormat(longFormat,
*fICULocale, longFormat ? fLongTimeFormat : fShortTimeFormat);
if (timeFormatter.Get() == NULL)
return B_NO_MEMORY;
SimpleDateFormat* timeFormatterImpl
= static_cast<SimpleDateFormat*>(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<NumberFormat> 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<NumberFormat> 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<NumberFormat> 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<SimpleDateFormat*>(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<SimpleDateFormat*>(timeFormatter);
UnicodeString pattern(format.String());
timeFormatterImpl->applyPattern(pattern);
}
return timeFormatter;
}
-1
View File
@@ -40,7 +40,6 @@ local sources =
IntegerFormat.cpp
IntegerFormatImpl.cpp
IntegerFormatParameters.cpp
langinfo.cpp
NumberFormat.cpp
NumberFormatImpl.cpp
NumberFormatParameters.cpp
+630 -7
View File
@@ -4,26 +4,81 @@
*/
#include <AutoDeleter.h>
#include <CalendarView.h>
#include <Catalog.h>
#include <Locale.h>
#include <LocaleRoster.h>
#include <unicode/datefmt.h>
#include <unicode/dcfmtsym.h>
#include <unicode/decimfmt.h>
#include <unicode/dtfmtsym.h>
#include <unicode/smpdtfmt.h>
#include <ICUWrapper.h>
static BLocale gLocale;
BLocale *be_locale = &gLocale;
#include <vector>
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<DateFormat> 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<DateFormat> 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<DateFormat> 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<int> 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<DateFormat> dateFormatter = CreateDateFormat(longFormat,
*fICULocale, longFormat ? fLongDateFormat : fShortDateFormat);
if (dateFormatter.Get() == NULL)
return B_NO_MEMORY;
SimpleDateFormat* dateFormatterImpl
= static_cast<SimpleDateFormat*>(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<DateFormat> 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<int> 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<DateFormat> 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<DateFormat> 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<DateFormat> 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<int> 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<DateFormat> 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<int> 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<DateFormat> timeFormatter = CreateTimeFormat(longFormat,
*fICULocale, longFormat ? fLongTimeFormat : fShortTimeFormat);
if (timeFormatter.Get() == NULL)
return B_NO_MEMORY;
SimpleDateFormat* timeFormatterImpl
= static_cast<SimpleDateFormat*>(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<NumberFormat> 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<NumberFormat> 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<NumberFormat> 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<SimpleDateFormat*>(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<SimpleDateFormat*>(timeFormatter);
UnicodeString pattern(format.String());
timeFormatterImpl->applyPattern(pattern);
}
return timeFormatter;
}
+19 -3
View File
@@ -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;
}
+53 -11
View File
@@ -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)
{
-20
View File
@@ -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 <Locale.h>
#include <langinfo.h>
char *
nl_langinfo(nl_item id)
{
if (be_locale != NULL)
be_locale->GetString(id);
// ToDo: return default values!
return (char*)"";
}
+31 -37
View File
@@ -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,
// &notificationMessage);
_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);
}
+5 -5
View File
@@ -7,7 +7,7 @@
#include <Box.h>
#include <Country.h>
#include <Locale.h>
#include <String.h>
#include <View.h>
@@ -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;
+7 -6
View File
@@ -7,6 +7,7 @@
#include "LocaleSettings.h"
#include <FindDirectory.h>
#include <Locale.h>
#include <MutableLocaleRoster.h>
#include <Path.h>
#include <String.h>
@@ -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);
}
+6 -6
View File
@@ -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;
}
+30 -30
View File
@@ -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);
+3 -1
View File
@@ -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;
}