Make BDateFormat inherit from BFormat again

* Move relevant parts up into BFormat so other format classes can use
those
* Adjust BDurationFormat and BTimeUnitFormat for the changes
* Remove the "default" date format, it is better to keep only a default
locale and let applications create B*Formats from it as needed.
* Creating a B*Format without arguments to the constructor now
configures it for the default locale, which allows for easy use in
standard cases (formatting something with the current language and
format)
* Creating a B*Format is potentially an expansive operation, it is
advised to keep the instance around and reuse it whenever possible.
However it must be "refreshed" when the locale changes, for apps which
supports that, since it keeps a copy of the language and formatting
convention, rather than a pointer to the locale as it did before.
This commit is contained in:
Adrien Destugues 2014-10-01 14:24:15 +02:00
parent 13d147b12b
commit 44f11d0982
12 changed files with 84 additions and 113 deletions

View File

@ -28,18 +28,15 @@ enum BWeekday {
};
class BDateFormat {
class BDateFormat: public BFormat {
public:
BDateFormat(const BLanguage* const,
const BFormattingConventions* const);
BDateFormat(
const BLanguage* const language = NULL,
const BFormattingConventions* const
format = NULL);
BDateFormat(const BDateFormat &other);
virtual ~BDateFormat();
static const BDateFormat* Default();
void SetLanguage(const BLanguage& newLanguage);
void SetFormattingConventions(
const BFormattingConventions& conventions);
status_t GetDateFormat(BDateFormatStyle style,
BString& outFormat) const;
void SetDateFormat(BDateFormatStyle style,
@ -73,9 +70,6 @@ private:
icu::DateFormat* _CreateDateFormatter(
const BString& format) const;
mutable BLocker fLock;
BFormattingConventions fConventions;
BLanguage fLanguage;
};

View File

@ -7,6 +7,7 @@
#include <Format.h>
#include <Locale.h>
#include <String.h>
#include <TimeUnitFormat.h>
@ -31,7 +32,7 @@ public:
void SetSeparator(const BString& separator);
virtual status_t SetLocale(const BLocale* locale);
virtual status_t SetLanguage(const BLanguage& language);
status_t SetTimeZone(const BTimeZone* timeZone);
status_t Format(bigtime_t startValue,

View File

@ -6,6 +6,9 @@
#define _B_FORMAT_H_
#include <FormatParameters.h>
#include <FormattingConventions.h>
#include <Locker.h>
#include <Language.h>
#include <SupportDefs.h>
@ -40,18 +43,25 @@ class BLocale;
class BFormat {
public:
status_t InitCheck() const;
status_t SetLocale(const BLocale& locale);
virtual status_t SetLanguage(const BLanguage& newLanguage);
virtual status_t SetFormattingConventions(
const BFormattingConventions&
conventions);
virtual status_t SetLocale(const BLocale* locale);
status_t InitCheck() const;
protected:
BFormat();
BFormat(const BFormat& other);
virtual ~BFormat();
BFormat();
BFormat(const BFormat& other);
virtual ~BFormat();
BFormat& operator=(const BFormat& other);
BFormat& operator=(const BFormat& other);
status_t fInitStatus;
BLocale* fLocale;
protected:
mutable BLocker fLock;
BFormattingConventions fConventions;
BLanguage fLanguage;
status_t fInitStatus;
};

View File

@ -79,7 +79,6 @@ public:
// (that needs to link with liblocalestub.a)
const BLocale* GetDefaultLocale() const;
const BDateFormat* GetDefaultDateFormat() const;
bool IsFilesystemTranslationPreferred() const;

View File

@ -46,7 +46,7 @@ public:
BTimeUnitFormat& operator=(const BTimeUnitFormat& other);
virtual status_t SetLocale(const BLocale* locale);
virtual status_t SetLanguage(const BLanguage& locale);
status_t Format(int32 value, time_unit_element unit,
BString* buffer,
time_unit_style style = B_TIME_UNIT_FULL

View File

@ -38,7 +38,6 @@ struct LocaleRosterData {
BLocale fDefaultLocale;
BTimeZone fDefaultTimeZone;
BDateFormat fDefaultDateFormat;
bool fIsFilesystemTranslationPreferred;

View File

@ -30,57 +30,23 @@ BDateFormat::BDateFormat(const BLanguage* const language,
{
if (conventions != NULL)
fConventions = *conventions;
else
BLocale::Default()->GetFormattingConventions(&fConventions);
if (language != NULL)
fLanguage = *language;
else
BLocale::Default()->GetLanguage(&fLanguage);
}
BDateFormat::BDateFormat(const BDateFormat &other)
: fConventions(other.fConventions),
fLanguage(other.fLanguage)
: BFormat(other)
{
}
/*static*/ const BDateFormat*
BDateFormat::Default()
{
return BLocaleRoster::Default()->GetDefaultDateFormat();
}
BDateFormat::~BDateFormat()
{
}
void
BDateFormat::SetFormattingConventions(const BFormattingConventions& conventions)
{
BAutolock lock(fLock);
if (!lock.IsLocked())
return;
fConventions = conventions;
}
void
BDateFormat::SetLanguage(const BLanguage& newLanguage)
{
BAutolock lock(fLock);
if (!lock.IsLocked())
return;
fLanguage = newLanguage;
}
status_t
BDateFormat::GetDateFormat(BDateFormatStyle style,
BString& outFormat) const

View File

@ -45,8 +45,6 @@ BDurationFormat::BDurationFormat(const BString& separator)
fInitStatus = B_NO_MEMORY;
return;
}
fInitStatus = SetLocale(fLocale);
}
@ -96,13 +94,13 @@ BDurationFormat::SetSeparator(const BString& separator)
status_t
BDurationFormat::SetLocale(const BLocale* locale)
BDurationFormat::SetLanguage(const BLanguage& language)
{
status_t result = Inherited::SetLocale(locale);
status_t result = Inherited::SetLanguage(language);
if (result != B_OK)
return result;
return fTimeUnitFormat.SetLocale(locale);
return fTimeUnitFormat.SetLanguage(language);
}

View File

@ -2,30 +2,30 @@
#include <new>
#include <Autolock.h>
#include <Locale.h>
#include <LocaleRoster.h>
BFormat::BFormat()
:
fInitStatus(B_NO_INIT),
fLocale(NULL)
{
const BLocale* locale = BLocaleRoster::Default()->GetDefaultLocale();
fInitStatus = locale->GetFormattingConventions(&fConventions);
if (fInitStatus == B_OK)
fInitStatus = locale->GetLanguage(&fLanguage);
}
BFormat::BFormat(const BFormat &other)
:
fInitStatus(other.fInitStatus),
fLocale(other.fLocale != NULL
? new (std::nothrow) BLocale(*other.fLocale)
: NULL)
{
fInitStatus = other.fInitStatus;
fConventions = other.fConventions;
fLanguage = other.fLanguage;
}
BFormat::~BFormat()
{
delete fLocale;
}
@ -36,12 +36,8 @@ BFormat::operator=(const BFormat& other)
return *this;
fInitStatus = other.fInitStatus;
delete fLocale;
fLocale = other.fLocale != NULL
? new (std::nothrow) BLocale(*other.fLocale) : NULL;
if (fLocale == NULL && other.fLocale != NULL)
fInitStatus = B_NO_MEMORY;
fLanguage = other.fLanguage;
fInitStatus = other.fInitStatus;
return *this;
}
@ -55,19 +51,47 @@ BFormat::InitCheck() const
status_t
BFormat::SetLocale(const BLocale* locale)
BFormat::SetLocale(const BLocale& locale)
{
if (locale != NULL) {
if (fLocale == NULL) {
fLocale = new (std::nothrow) BLocale(*locale);
if (fLocale == NULL)
return B_NO_MEMORY;
} else
*fLocale = *locale;
} else {
delete fLocale;
fLocale = NULL;
}
BFormattingConventions conventions;
BLanguage language;
fInitStatus = locale.GetFormattingConventions(&conventions);
if (fInitStatus != B_OK)
return fInitStatus;
fInitStatus = SetFormattingConventions(conventions);
if (fInitStatus != B_OK)
return fInitStatus;
fInitStatus = locale.GetLanguage(&language);
if (fInitStatus != B_OK)
return fInitStatus;
fInitStatus = SetLanguage(language);
return fInitStatus;
}
status_t
BFormat::SetFormattingConventions(const BFormattingConventions& conventions)
{
BAutolock lock(fLock);
if (!lock.IsLocked())
return B_WOULD_BLOCK;
fConventions = conventions;
return B_OK;
}
status_t
BFormat::SetLanguage(const BLanguage& newLanguage)
{
BAutolock lock(fLock);
if (!lock.IsLocked())
return B_WOULD_BLOCK;
fLanguage = newLanguage;
return B_OK;
}

View File

@ -175,13 +175,6 @@ BLocaleRoster::GetDefaultLocale() const
}
const BDateFormat*
BLocaleRoster::GetDefaultDateFormat() const
{
return &fData->fDefaultDateFormat;
}
status_t
BLocaleRoster::GetLanguage(const char* languageCode,
BLanguage** _language) const

View File

@ -126,7 +126,6 @@ LocaleRosterData::LocaleRosterData(const BLanguage& language,
:
fLock("LocaleRosterData"),
fDefaultLocale(&language, &conventions),
fDefaultDateFormat(&language, &conventions),
fIsFilesystemTranslationPreferred(false),
fAreResourcesLoaded(false)
{
@ -467,7 +466,6 @@ LocaleRosterData::_LoadLocaleSettings()
if (status == B_OK) {
BFormattingConventions conventions(&settings);
fDefaultLocale.SetFormattingConventions(conventions);
fDefaultDateFormat.SetFormattingConventions(conventions);
_SetPreferredLanguages(&settings);
@ -486,10 +484,8 @@ LocaleRosterData::_LoadLocaleSettings()
fPreferredLanguages.AddString(kLanguageField, "en");
BLanguage defaultLanguage("en_US");
fDefaultLocale.SetLanguage(defaultLanguage);
fDefaultDateFormat.SetLanguage(defaultLanguage);
BFormattingConventions conventions("en_US");
fDefaultLocale.SetFormattingConventions(conventions);
fDefaultDateFormat.SetFormattingConventions(conventions);
return status;
}
@ -585,7 +581,6 @@ LocaleRosterData::_SetDefaultFormattingConventions(
const BFormattingConventions& newFormattingConventions)
{
fDefaultLocale.SetFormattingConventions(newFormattingConventions);
fDefaultDateFormat.SetFormattingConventions(newFormattingConventions);
UErrorCode icuError = U_ZERO_ERROR;
Locale icuLocale = Locale::createCanonical(newFormattingConventions.ID());
@ -622,7 +617,6 @@ LocaleRosterData::_SetPreferredLanguages(const BMessage* languages)
&& languages->FindString(kLanguageField, &langName) == B_OK) {
fDefaultLocale.SetCollator(BCollator(langName.String()));
fDefaultLocale.SetLanguage(BLanguage(langName.String()));
fDefaultDateFormat.SetLanguage(BLanguage(langName.String()));
fPreferredLanguages.RemoveName(kLanguageField);
for (int i = 0; languages->FindString(kLanguageField, i, &langName)

View File

@ -39,7 +39,6 @@ BTimeUnitFormat::BTimeUnitFormat()
Inherited(),
fFormatter(NULL)
{
fInitStatus = SetLocale(fLocale);
}
@ -80,19 +79,13 @@ BTimeUnitFormat::operator=(const BTimeUnitFormat& other)
status_t
BTimeUnitFormat::SetLocale(const BLocale* locale)
BTimeUnitFormat::SetLanguage(const BLanguage& language)
{
status_t result = Inherited::SetLocale(locale);
status_t result = Inherited::SetLanguage(language);
if (result != B_OK)
return result;
BLanguage language;
if (fLocale != NULL)
fLocale->GetLanguage(&language);
else
BLocale::Default()->GetLanguage(&language);
Locale icuLocale(language.Code());
Locale icuLocale(fLanguage.Code());
UErrorCode icuStatus = U_ZERO_ERROR;
if (fFormatter == NULL) {
fFormatter = new TimeUnitFormat(icuLocale, icuStatus);