Next step of Locale Kit refactoring:
* BLocale now keeps language and country completely separate and mixes the formatting conventions into the current language's locale when formatting dates and times (needs to be done for number- and currency-formatting, too, since the digits may not be in the preferred language) * optimized fetching of the flag icons such that they are all loaded in one go (by the locale roster) - this alone speeds up the Locale preflet considerably * worked on fixing the language confusion in the Locale preflet * fixed a couple of bugs in the Locale preflet that would lead to illegal characters being displayed in the date-subpart menus git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39013 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
1959f8502b
commit
d1d8fda637
@ -13,6 +13,7 @@
|
||||
|
||||
|
||||
class BBitmap;
|
||||
class BLanguage;
|
||||
class BMessage;
|
||||
|
||||
namespace icu_44 {
|
||||
@ -37,7 +38,11 @@ public:
|
||||
BCountry& operator=(const BCountry& other);
|
||||
~BCountry();
|
||||
|
||||
bool GetName(BString& name) const;
|
||||
status_t GetNativeName(BString& name) const;
|
||||
status_t GetName(BString& name,
|
||||
const BLanguage* displayLanguage = NULL
|
||||
) const;
|
||||
|
||||
const char* Code() const;
|
||||
status_t GetIcon(BBitmap* result) const;
|
||||
|
||||
@ -48,7 +53,10 @@ public:
|
||||
|
||||
int8 Measurement() const;
|
||||
|
||||
class Private;
|
||||
private:
|
||||
friend class Private;
|
||||
|
||||
icu_44::Locale* fICULocale;
|
||||
};
|
||||
|
||||
|
@ -34,12 +34,17 @@ public:
|
||||
|
||||
BLanguage& operator=(const BLanguage& source);
|
||||
|
||||
status_t GetName(BString& name) const;
|
||||
status_t GetTranslatedName(BString& name) const;
|
||||
status_t GetNativeName(BString& name) const;
|
||||
status_t GetName(BString& name,
|
||||
const BLanguage* displayLanguage = NULL
|
||||
) const;
|
||||
|
||||
// ISO-639 language code, e.g. "en", "de"
|
||||
const char* Code() const;
|
||||
const char* Country() const;
|
||||
// ISO-639-1
|
||||
const char* CountryCode() const;
|
||||
// ISO-3166
|
||||
const char* ScriptCode() const;
|
||||
// ISO-15924
|
||||
const char* Variant() const;
|
||||
const char* ID() const;
|
||||
|
||||
@ -50,10 +55,12 @@ public:
|
||||
|
||||
status_t SetTo(const char* language);
|
||||
|
||||
// see definitions below
|
||||
const char* GetString(uint32 id) const;
|
||||
|
||||
class Private;
|
||||
private:
|
||||
friend class Private;
|
||||
|
||||
// BString fStrings[B_NUM_LANGUAGE_STRINGS];
|
||||
uint8 fDirection;
|
||||
icu_44::Locale* fICULocale;
|
||||
|
@ -38,8 +38,8 @@ typedef enum {
|
||||
|
||||
class BLocale {
|
||||
public:
|
||||
BLocale(const char* languageAndCountryCode
|
||||
= "en_US");
|
||||
BLocale(const BLanguage* language = NULL,
|
||||
const BCountry* country = NULL);
|
||||
BLocale(const BLocale& other);
|
||||
~BLocale();
|
||||
|
||||
@ -48,12 +48,12 @@ public:
|
||||
status_t GetCollator(BCollator* collator) const;
|
||||
status_t GetLanguage(BLanguage* language) const;
|
||||
status_t GetCountry(BCountry* country) const;
|
||||
const char* Code() const;
|
||||
bool GetName(BString& name) const;
|
||||
|
||||
void SetCountry(const BCountry& newCountry);
|
||||
void SetCollator(const BCollator& newCollator);
|
||||
void SetLanguage(const char* languageCode);
|
||||
void SetLanguage(const BLanguage& newLanguage);
|
||||
|
||||
bool GetName(BString& name) const;
|
||||
|
||||
// see definitions in LocaleStrings.h
|
||||
const char* GetString(uint32 id) const;
|
||||
@ -140,17 +140,19 @@ public:
|
||||
void GetSortKey(const char* string,
|
||||
BString* key) const;
|
||||
|
||||
protected:
|
||||
private:
|
||||
void _UpdateFormats();
|
||||
|
||||
mutable BLocker fLock;
|
||||
BCollator fCollator;
|
||||
BCountry fCountry;
|
||||
BLanguage fLanguage;
|
||||
|
||||
icu_44::Locale* fICULocale;
|
||||
BString fLongDateFormat;
|
||||
BString fShortDateFormat;
|
||||
BString fLongTimeFormat;
|
||||
BString fShortTimeFormat;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <String.h>
|
||||
|
||||
|
||||
class BBitmap;
|
||||
class BCatalog;
|
||||
class BCollator;
|
||||
class BCountry;
|
||||
@ -48,6 +49,9 @@ public:
|
||||
BMessage* message,
|
||||
const char* countryCode) const;
|
||||
|
||||
status_t GetFlagIconForCountry(BBitmap* flagIcon,
|
||||
const char* countryCode);
|
||||
|
||||
status_t GetInstalledCatalogs(BMessage* message,
|
||||
const char* sigPattern = NULL,
|
||||
const char* langPattern = NULL,
|
||||
|
@ -46,8 +46,8 @@ public:
|
||||
private:
|
||||
friend class Private;
|
||||
|
||||
icu_44::TimeZone* fIcuTimeZone;
|
||||
icu_44::Locale* fIcuLocale;
|
||||
icu_44::TimeZone* fICUTimeZone;
|
||||
icu_44::Locale* fICULocale;
|
||||
status_t fInitStatus;
|
||||
|
||||
mutable uint32 fInitializedFields;
|
||||
|
37
headers/private/locale/CountryPrivate.h
Normal file
37
headers/private/locale/CountryPrivate.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2010, Oliver Tappe <zooey@hirschkaefer.de>
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _COUNTRY_PRIVATE_H
|
||||
#define _COUNTRY_PRIVATE_H
|
||||
|
||||
|
||||
#include <Country.h>
|
||||
|
||||
|
||||
class BCountry::Private {
|
||||
public:
|
||||
Private(const BCountry* country = NULL)
|
||||
:
|
||||
fCountry(country)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
SetTo(const BCountry* country)
|
||||
{
|
||||
fCountry = country;
|
||||
}
|
||||
|
||||
icu_44::Locale*
|
||||
ICULocale()
|
||||
{
|
||||
return fCountry->fICULocale;
|
||||
}
|
||||
|
||||
private:
|
||||
const BCountry* fCountry;
|
||||
};
|
||||
|
||||
|
||||
#endif // _COUNTRY_PRIVATE_H
|
37
headers/private/locale/LanguagePrivate.h
Normal file
37
headers/private/locale/LanguagePrivate.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2010, Oliver Tappe <zooey@hirschkaefer.de>
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _LANGUAGE_PRIVATE_H
|
||||
#define _LANGUAGE_PRIVATE_H
|
||||
|
||||
|
||||
#include <Language.h>
|
||||
|
||||
|
||||
class BLanguage::Private {
|
||||
public:
|
||||
Private(const BLanguage* language = NULL)
|
||||
:
|
||||
fLanguage(language)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
SetTo(const BLanguage* language)
|
||||
{
|
||||
fLanguage = language;
|
||||
}
|
||||
|
||||
icu_44::Locale*
|
||||
ICULocale()
|
||||
{
|
||||
return fLanguage->fICULocale;
|
||||
}
|
||||
|
||||
private:
|
||||
const BLanguage* fLanguage;
|
||||
};
|
||||
|
||||
|
||||
#endif // _LANGUAGE_PRIVATE_H
|
@ -15,6 +15,7 @@
|
||||
#include <Locker.h>
|
||||
#include <LocaleRoster.h>
|
||||
#include <Message.h>
|
||||
#include <Resources.h>
|
||||
#include <TimeZone.h>
|
||||
|
||||
|
||||
@ -113,6 +114,9 @@ struct RosterData {
|
||||
BLocale fDefaultLocale;
|
||||
BTimeZone fDefaultTimeZone;
|
||||
|
||||
bool fAreResourcesLoaded;
|
||||
BResources fResources;
|
||||
|
||||
RosterData();
|
||||
~RosterData();
|
||||
|
||||
|
@ -24,9 +24,9 @@ public:
|
||||
}
|
||||
|
||||
icu_44::TimeZone*
|
||||
IcuTimeZone()
|
||||
ICUTimeZone()
|
||||
{
|
||||
return fTimeZone->fIcuTimeZone;
|
||||
return fTimeZone->fICUTimeZone;
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -182,7 +182,7 @@ TranslationComparator(const void* left, const void* right)
|
||||
BString leftName;
|
||||
if (be_locale_roster->GetLanguage(leftTranslation->languageCode, &language)
|
||||
== B_OK) {
|
||||
language->GetTranslatedName(leftName);
|
||||
language->GetName(leftName);
|
||||
delete language;
|
||||
} else
|
||||
leftName = leftTranslation->languageCode;
|
||||
@ -190,7 +190,7 @@ TranslationComparator(const void* left, const void* right)
|
||||
BString rightName;
|
||||
if (be_locale_roster->GetLanguage(rightTranslation->languageCode, &language)
|
||||
== B_OK) {
|
||||
language->GetTranslatedName(rightName);
|
||||
language->GetName(rightName);
|
||||
delete language;
|
||||
} else
|
||||
rightName = rightTranslation->languageCode;
|
||||
@ -1101,7 +1101,7 @@ AboutView::_CreateCreditsView()
|
||||
langName.Truncate(0);
|
||||
if (be_locale_roster->GetLanguage(translation.languageCode, &lang)
|
||||
== B_OK) {
|
||||
lang->GetTranslatedName(langName);
|
||||
lang->GetName(langName);
|
||||
delete lang;
|
||||
} else {
|
||||
// We failed to get the localized readable name,
|
||||
|
@ -1587,7 +1587,7 @@ MainWin::_SetupTrackMenus(BMenu* audioTrackMenu, BMenu* videoTrackMenu,
|
||||
if (languageString != NULL) {
|
||||
BLanguage language(languageString);
|
||||
BString languageName;
|
||||
if (language.GetTranslatedName(languageName) == B_OK)
|
||||
if (language.GetName(languageName) == B_OK)
|
||||
languageString = languageName.String();
|
||||
snprintf(s, sizeof(s), "%s", languageString);
|
||||
} else
|
||||
|
@ -260,6 +260,9 @@ BootPromptWindow::_PopulateLanguages()
|
||||
be_locale_roster->GetInstalledCatalogs(&installedCatalogs,
|
||||
"x-vnd.Haiku-ReadOnlyBootPrompt");
|
||||
|
||||
BFont font;
|
||||
fLanguagesListView->GetFont(&font);
|
||||
|
||||
// Try to instantiate a BCatalog for each language, it will only work
|
||||
// for translations of this application. So the list of languages will be
|
||||
// limited to catalogs written for this application, which is on purpose!
|
||||
@ -270,14 +273,16 @@ BootPromptWindow::_PopulateLanguages()
|
||||
BLanguage* language;
|
||||
if (be_locale_roster->GetLanguage(languageString, &language) == B_OK) {
|
||||
BString name;
|
||||
language->GetName(name);
|
||||
language->GetNativeName(name);
|
||||
|
||||
// TODO: as long as the app_server doesn't support font overlays,
|
||||
// use the translated name if problematic characters are used...
|
||||
const char* string = name.String();
|
||||
while (uint32 code = BUnicodeChar::FromUTF8(&string)) {
|
||||
if (code > 1424) {
|
||||
language->GetTranslatedName(name);
|
||||
// TODO: the following block fails to detect a couple of language
|
||||
// names as containing glyphs we can't render. Why's that?
|
||||
bool hasGlyphs[name.CountChars()];
|
||||
font.GetHasGlyphs(name.String(), name.CountChars(), hasGlyphs);
|
||||
for (int32 i = 0; i < name.CountChars(); ++i) {
|
||||
if (!hasGlyphs[i]) {
|
||||
// replace by name translated to current language
|
||||
language->GetName(name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <AutoDeleter.h>
|
||||
#include <IconUtils.h>
|
||||
#include <List.h>
|
||||
#include <Language.h>
|
||||
#include <LocaleRoster.h>
|
||||
#include <Resources.h>
|
||||
#include <String.h>
|
||||
@ -68,14 +69,39 @@ BCountry::~BCountry()
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BCountry::GetName(BString& name) const
|
||||
status_t
|
||||
BCountry::GetNativeName(BString& name) const
|
||||
{
|
||||
UnicodeString string;
|
||||
fICULocale->getDisplayName(*fICULocale, string);
|
||||
string.toTitle(NULL, *fICULocale);
|
||||
|
||||
name.Truncate(0);
|
||||
BStringByteSink converter(&name);
|
||||
string.toUTF8(converter);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BCountry::GetName(BString& name, const BLanguage* displayLanguage) const
|
||||
{
|
||||
BString appLanguage;
|
||||
if (displayLanguage == NULL) {
|
||||
BMessage preferredLanguage;
|
||||
be_locale_roster->GetPreferredLanguages(&preferredLanguage);
|
||||
preferredLanguage.FindString("language", 0, &appLanguage);
|
||||
} else {
|
||||
appLanguage = displayLanguage->Code();
|
||||
}
|
||||
|
||||
UnicodeString uString;
|
||||
fICULocale->getDisplayCountry(uString);
|
||||
fICULocale->getDisplayName(Locale(appLanguage), uString);
|
||||
BStringByteSink stringConverter(&name);
|
||||
uString.toUTF8(stringConverter);
|
||||
return true;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -89,23 +115,10 @@ BCountry::Code() const
|
||||
status_t
|
||||
BCountry::GetIcon(BBitmap* result) const
|
||||
{
|
||||
if (result == NULL)
|
||||
return B_BAD_DATA;
|
||||
// TODO: a proper way to locate the library being used ?
|
||||
BResources storage("/boot/system/lib/liblocale.so");
|
||||
if (storage.InitCheck() != B_OK)
|
||||
return B_ERROR;
|
||||
size_t size;
|
||||
const char* code = fICULocale->getCountry();
|
||||
if (code != NULL) {
|
||||
const void* buffer = storage.LoadResource(B_VECTOR_ICON_TYPE, code,
|
||||
&size);
|
||||
if (buffer != NULL && size != 0) {
|
||||
return BIconUtils::GetVectorIcon(static_cast<const uint8*>(buffer),
|
||||
size, result);
|
||||
}
|
||||
}
|
||||
return B_BAD_DATA;
|
||||
if (code == NULL)
|
||||
return B_ERROR;
|
||||
return be_locale_roster->GetFlagIconForCountry(result, code);
|
||||
}
|
||||
|
||||
|
||||
|
@ -123,7 +123,7 @@ BDurationFormat::SetTimeZone(const BTimeZone* timeZone)
|
||||
} else
|
||||
zonePrivate.SetTo(timeZone);
|
||||
|
||||
TimeZone* icuTimeZone = zonePrivate.IcuTimeZone();
|
||||
TimeZone* icuTimeZone = zonePrivate.ICUTimeZone();
|
||||
if (icuTimeZone != NULL)
|
||||
fCalendar->setTimeZone(*icuTimeZone);
|
||||
|
||||
|
@ -110,10 +110,11 @@ BLanguage::GetString(uint32 id) const
|
||||
|
||||
|
||||
status_t
|
||||
BLanguage::GetName(BString& name) const
|
||||
BLanguage::GetNativeName(BString& name) const
|
||||
{
|
||||
UnicodeString string;
|
||||
fICULocale->getDisplayName(*fICULocale, string);
|
||||
string.toTitle(NULL, *fICULocale);
|
||||
|
||||
name.Truncate(0);
|
||||
BStringByteSink converter(&name);
|
||||
@ -124,13 +125,16 @@ BLanguage::GetName(BString& name) const
|
||||
|
||||
|
||||
status_t
|
||||
BLanguage::GetTranslatedName(BString& name) const
|
||||
BLanguage::GetName(BString& name, const BLanguage* displayLanguage) const
|
||||
{
|
||||
BMessage preferredLanguage;
|
||||
be_locale_roster->GetPreferredLanguages(&preferredLanguage);
|
||||
|
||||
BString appLanguage;
|
||||
preferredLanguage.FindString("language", 0, &appLanguage);
|
||||
if (displayLanguage == NULL) {
|
||||
BMessage preferredLanguage;
|
||||
be_locale_roster->GetPreferredLanguages(&preferredLanguage);
|
||||
preferredLanguage.FindString("language", 0, &appLanguage);
|
||||
} else {
|
||||
appLanguage = displayLanguage->Code();
|
||||
}
|
||||
|
||||
UnicodeString string;
|
||||
fICULocale->getDisplayName(Locale(appLanguage), string);
|
||||
@ -151,7 +155,7 @@ BLanguage::Code() const
|
||||
|
||||
|
||||
const char*
|
||||
BLanguage::Country() const
|
||||
BLanguage::CountryCode() const
|
||||
{
|
||||
const char* country = fICULocale->getCountry();
|
||||
if (country == NULL || country[0] == '\0')
|
||||
@ -161,6 +165,17 @@ BLanguage::Country() const
|
||||
}
|
||||
|
||||
|
||||
const char*
|
||||
BLanguage::ScriptCode() const
|
||||
{
|
||||
const char* script = fICULocale->getScript();
|
||||
if (script == NULL || script[0] == '\0')
|
||||
return NULL;
|
||||
|
||||
return script;
|
||||
}
|
||||
|
||||
|
||||
const char*
|
||||
BLanguage::Variant() const
|
||||
{
|
||||
@ -182,7 +197,7 @@ BLanguage::ID() const
|
||||
bool
|
||||
BLanguage::IsCountrySpecific() const
|
||||
{
|
||||
return Country() != NULL;
|
||||
return CountryCode() != NULL;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*
|
||||
** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
** Distributed under the terms of the OpenBeOS License.
|
||||
** Copyright 2003, Axel Dörfler, axeld@pinc-software.de.
|
||||
** Copyright 2010, Oliver Tappe, zooey@hirschkaefer.de.
|
||||
** All rights reserved. Distributed under the terms of the OpenBeOS License.
|
||||
*/
|
||||
|
||||
|
||||
@ -8,6 +9,8 @@
|
||||
#include <Autolock.h>
|
||||
#include <CalendarView.h>
|
||||
#include <Catalog.h>
|
||||
#include <CountryPrivate.h>
|
||||
#include <LanguagePrivate.h>
|
||||
#include <Locale.h>
|
||||
#include <LocaleRoster.h>
|
||||
#include <MutableLocaleRoster.h>
|
||||
@ -37,14 +40,25 @@ static DateFormat* CreateDateFormat(bool longFormat, const Locale& locale,
|
||||
const BString& format);
|
||||
static DateFormat* CreateTimeFormat(bool longFormat, const Locale& locale,
|
||||
const BString& format);
|
||||
static void FetchDateFormat(bool longFormat, const Locale& locale,
|
||||
BString& format);
|
||||
static void FetchTimeFormat(bool longFormat, const Locale& locale,
|
||||
BString& format);
|
||||
|
||||
|
||||
BLocale::BLocale(const char* languageAndCountryCode)
|
||||
:
|
||||
fCountry(languageAndCountryCode),
|
||||
fLanguage(languageAndCountryCode),
|
||||
fICULocale(new ICU_VERSION::Locale(languageAndCountryCode))
|
||||
BLocale::BLocale(const BLanguage* language, const BCountry* country)
|
||||
{
|
||||
if (country != NULL)
|
||||
fCountry = *country;
|
||||
else
|
||||
be_locale->GetCountry(&fCountry);
|
||||
|
||||
if (language != NULL)
|
||||
fLanguage = *language;
|
||||
else
|
||||
be_locale->GetLanguage(&fLanguage);
|
||||
|
||||
_UpdateFormats();
|
||||
}
|
||||
|
||||
|
||||
@ -52,7 +66,6 @@ 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),
|
||||
@ -67,8 +80,6 @@ BLocale::operator=(const BLocale& other)
|
||||
if (this == &other)
|
||||
return *this;
|
||||
|
||||
*fICULocale = *other.fICULocale;
|
||||
|
||||
fLongDateFormat = other.fLongDateFormat;
|
||||
fShortDateFormat = other.fShortDateFormat;
|
||||
fLongTimeFormat = other.fLongTimeFormat;
|
||||
@ -83,7 +94,6 @@ BLocale::operator=(const BLocale& other)
|
||||
|
||||
BLocale::~BLocale()
|
||||
{
|
||||
delete fICULocale;
|
||||
}
|
||||
|
||||
|
||||
@ -140,6 +150,10 @@ BLocale::GetString(uint32 id) const
|
||||
{
|
||||
// Note: this code assumes a certain order of the string bases
|
||||
|
||||
BAutolock lock(fLock);
|
||||
if (!lock.IsLocked())
|
||||
return "";
|
||||
|
||||
if (id >= B_OTHER_STRINGS_BASE) {
|
||||
if (id == B_CODESET)
|
||||
return "UTF-8";
|
||||
@ -153,41 +167,54 @@ BLocale::GetString(uint32 id) const
|
||||
void
|
||||
BLocale::SetCountry(const BCountry& newCountry)
|
||||
{
|
||||
BAutolock lock(fLock);
|
||||
if (!lock.IsLocked())
|
||||
return;
|
||||
|
||||
fCountry = newCountry;
|
||||
|
||||
_UpdateFormats();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BLocale::SetCollator(const BCollator& newCollator)
|
||||
{
|
||||
BAutolock lock(fLock);
|
||||
if (!lock.IsLocked())
|
||||
return;
|
||||
|
||||
fCollator = newCollator;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BLocale::SetLanguage(const char* languageCode)
|
||||
BLocale::SetLanguage(const BLanguage& newLanguage)
|
||||
{
|
||||
fLanguage.SetTo(languageCode);
|
||||
}
|
||||
BAutolock lock(fLock);
|
||||
if (!lock.IsLocked())
|
||||
return;
|
||||
|
||||
|
||||
const char*
|
||||
BLocale::Code() const
|
||||
{
|
||||
return fICULocale->getName();
|
||||
fLanguage = newLanguage;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BLocale::GetName(BString& name) const
|
||||
{
|
||||
Locale icuLocale = Locale::createCanonical(fCountry.Code());
|
||||
if (icuLocale.isBogus())
|
||||
return false;
|
||||
|
||||
UnicodeString uString;
|
||||
fICULocale->getDisplayName(uString);
|
||||
const Locale* countryLocale = BCountry::Private(&fCountry).ICULocale();
|
||||
countryLocale->getDisplayName(icuLocale, uString);
|
||||
BStringByteSink stringConverter(&name);
|
||||
uString.toUTF8(stringConverter);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - Date
|
||||
|
||||
|
||||
@ -195,8 +222,13 @@ status_t
|
||||
BLocale::FormatDate(char* string, size_t maxSize, time_t time,
|
||||
bool longFormat) const
|
||||
{
|
||||
BAutolock lock(fLock);
|
||||
if (!lock.IsLocked())
|
||||
return B_ERROR;
|
||||
|
||||
ObjectDeleter<DateFormat> dateFormatter = CreateDateFormat(longFormat,
|
||||
*fICULocale, longFormat ? fLongDateFormat : fShortDateFormat);
|
||||
*BLanguage::Private(&fLanguage).ICULocale(),
|
||||
longFormat ? fLongDateFormat : fShortDateFormat);
|
||||
if (dateFormatter.Get() == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
@ -204,7 +236,6 @@ BLocale::FormatDate(char* string, size_t maxSize, time_t time,
|
||||
ICUString = dateFormatter->format((UDate)time * 1000, ICUString);
|
||||
|
||||
CheckedArrayByteSink stringConverter(string, maxSize);
|
||||
|
||||
ICUString.toUTF8(stringConverter);
|
||||
|
||||
if (stringConverter.Overflowed())
|
||||
@ -218,12 +249,13 @@ status_t
|
||||
BLocale::FormatDate(BString *string, time_t time, bool longFormat,
|
||||
const BTimeZone* timeZone) const
|
||||
{
|
||||
string->Truncate(0);
|
||||
// We make the string empty, this way even in cases where ICU fail we at
|
||||
// least return something sane
|
||||
Locale locale(fLanguage.Code());
|
||||
BAutolock lock(fLock);
|
||||
if (!lock.IsLocked())
|
||||
return B_ERROR;
|
||||
|
||||
ObjectDeleter<DateFormat> dateFormatter = CreateDateFormat(longFormat,
|
||||
locale, longFormat ? fLongDateFormat : fShortDateFormat);
|
||||
*BLanguage::Private(&fLanguage).ICULocale(),
|
||||
longFormat ? fLongDateFormat : fShortDateFormat);
|
||||
if (dateFormatter.Get() == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
@ -238,6 +270,7 @@ BLocale::FormatDate(BString *string, time_t time, bool longFormat,
|
||||
UnicodeString ICUString;
|
||||
ICUString = dateFormatter->format((UDate)time * 1000, ICUString);
|
||||
|
||||
string->Truncate(0);
|
||||
BStringByteSink stringConverter(string);
|
||||
ICUString.toUTF8(stringConverter);
|
||||
|
||||
@ -249,10 +282,13 @@ status_t
|
||||
BLocale::FormatDate(BString* string, int*& fieldPositions, int& fieldCount,
|
||||
time_t time, bool longFormat) const
|
||||
{
|
||||
string->Truncate(0);
|
||||
BAutolock lock(fLock);
|
||||
if (!lock.IsLocked())
|
||||
return B_ERROR;
|
||||
|
||||
ObjectDeleter<DateFormat> dateFormatter = CreateDateFormat(longFormat,
|
||||
*fICULocale, longFormat ? fLongDateFormat : fShortDateFormat);
|
||||
*BLanguage::Private(&fLanguage).ICULocale(),
|
||||
longFormat ? fLongDateFormat : fShortDateFormat);
|
||||
if (dateFormatter.Get() == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
@ -280,6 +316,7 @@ BLocale::FormatDate(BString* string, int*& fieldPositions, int& fieldCount,
|
||||
for (int i = 0 ; i < fieldCount ; i++ )
|
||||
fieldPositions[i] = fieldPosStorage[i];
|
||||
|
||||
string->Truncate(0);
|
||||
BStringByteSink stringConverter(string);
|
||||
|
||||
ICUString.toUTF8(stringConverter);
|
||||
@ -291,6 +328,10 @@ BLocale::FormatDate(BString* string, int*& fieldPositions, int& fieldCount,
|
||||
status_t
|
||||
BLocale::GetDateFormat(BString& format, bool longFormat) const
|
||||
{
|
||||
BAutolock lock(fLock);
|
||||
if (!lock.IsLocked())
|
||||
return B_ERROR;
|
||||
|
||||
if (longFormat && fLongDateFormat.Length() > 0)
|
||||
format = fLongDateFormat;
|
||||
else if (!longFormat && fShortDateFormat.Length() > 0)
|
||||
@ -299,7 +340,7 @@ BLocale::GetDateFormat(BString& format, bool longFormat) const
|
||||
format.Truncate(0);
|
||||
|
||||
ObjectDeleter<DateFormat> dateFormatter = CreateDateFormat(longFormat,
|
||||
*fICULocale, longFormat ? fLongDateFormat : fShortDateFormat);
|
||||
*BCountry::Private(&fCountry).ICULocale(), format);
|
||||
if (dateFormatter.Get() == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
@ -321,6 +362,10 @@ BLocale::GetDateFormat(BString& format, bool longFormat) const
|
||||
status_t
|
||||
BLocale::SetDateFormat(const char* formatString, bool longFormat)
|
||||
{
|
||||
BAutolock lock(fLock);
|
||||
if (!lock.IsLocked())
|
||||
return B_ERROR;
|
||||
|
||||
if (longFormat)
|
||||
fLongDateFormat = formatString;
|
||||
else
|
||||
@ -334,8 +379,13 @@ status_t
|
||||
BLocale::GetDateFields(BDateElement*& fields, int& fieldCount,
|
||||
bool longFormat) const
|
||||
{
|
||||
BAutolock lock(fLock);
|
||||
if (!lock.IsLocked())
|
||||
return B_ERROR;
|
||||
|
||||
ObjectDeleter<DateFormat> dateFormatter = CreateDateFormat(longFormat,
|
||||
*fICULocale, longFormat ? fLongDateFormat : fShortDateFormat);
|
||||
*BCountry::Private(&fCountry).ICULocale(),
|
||||
longFormat ? fLongDateFormat : fShortDateFormat);
|
||||
if (dateFormatter.Get() == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
@ -384,8 +434,14 @@ BLocale::GetDateFields(BDateElement*& fields, int& fieldCount,
|
||||
int
|
||||
BLocale::StartOfWeek() const
|
||||
{
|
||||
BAutolock lock(fLock);
|
||||
if (!lock.IsLocked())
|
||||
return B_ERROR;
|
||||
|
||||
UErrorCode err = U_ZERO_ERROR;
|
||||
Calendar* c = Calendar::createInstance(*fICULocale, err);
|
||||
Calendar* c
|
||||
= Calendar::createInstance(*BCountry::Private(&fCountry).ICULocale(),
|
||||
err);
|
||||
|
||||
if (err == U_ZERO_ERROR && c->getFirstDayOfWeek(err) == UCAL_SUNDAY) {
|
||||
delete c;
|
||||
@ -402,13 +458,19 @@ status_t
|
||||
BLocale::FormatDateTime(char* target, size_t maxSize, time_t time,
|
||||
bool longFormat) const
|
||||
{
|
||||
BAutolock lock(fLock);
|
||||
if (!lock.IsLocked())
|
||||
return B_ERROR;
|
||||
|
||||
ObjectDeleter<DateFormat> dateFormatter = CreateDateFormat(longFormat,
|
||||
*fICULocale, longFormat ? fLongDateFormat : fShortDateFormat);
|
||||
*BLanguage::Private(&fLanguage).ICULocale(),
|
||||
longFormat ? fLongDateFormat : fShortDateFormat);
|
||||
if (dateFormatter.Get() == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
ObjectDeleter<DateFormat> timeFormatter = CreateTimeFormat(longFormat,
|
||||
*fICULocale, longFormat ? fLongTimeFormat : fShortTimeFormat);
|
||||
*BLanguage::Private(&fLanguage).ICULocale(),
|
||||
longFormat ? fLongTimeFormat : fShortTimeFormat);
|
||||
if (timeFormatter.Get() == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
@ -433,13 +495,19 @@ status_t
|
||||
BLocale::FormatDateTime(BString* target, time_t time, bool longFormat,
|
||||
const BTimeZone* timeZone) const
|
||||
{
|
||||
BAutolock lock(fLock);
|
||||
if (!lock.IsLocked())
|
||||
return B_ERROR;
|
||||
|
||||
ObjectDeleter<DateFormat> dateFormatter = CreateDateFormat(longFormat,
|
||||
*fICULocale, longFormat ? fLongDateFormat : fShortDateFormat);
|
||||
*BLanguage::Private(&fLanguage).ICULocale(),
|
||||
longFormat ? fLongDateFormat : fShortDateFormat);
|
||||
if (dateFormatter.Get() == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
ObjectDeleter<DateFormat> timeFormatter = CreateTimeFormat(longFormat,
|
||||
*fICULocale, longFormat ? fLongTimeFormat : fShortTimeFormat);
|
||||
*BLanguage::Private(&fLanguage).ICULocale(),
|
||||
longFormat ? fLongTimeFormat : fShortTimeFormat);
|
||||
if (timeFormatter.Get() == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
@ -458,6 +526,7 @@ BLocale::FormatDateTime(BString* target, time_t time, bool longFormat,
|
||||
|
||||
ICUString = timeFormatter->format((UDate)time * 1000, ICUString);
|
||||
|
||||
target->Truncate(0);
|
||||
BStringByteSink stringConverter(target);
|
||||
ICUString.toUTF8(stringConverter);
|
||||
|
||||
@ -472,8 +541,13 @@ status_t
|
||||
BLocale::FormatTime(char* string, size_t maxSize, time_t time,
|
||||
bool longFormat) const
|
||||
{
|
||||
BAutolock lock(fLock);
|
||||
if (!lock.IsLocked())
|
||||
return B_ERROR;
|
||||
|
||||
ObjectDeleter<DateFormat> timeFormatter = CreateTimeFormat(longFormat,
|
||||
*fICULocale, longFormat ? fLongTimeFormat : fShortTimeFormat);
|
||||
*BLanguage::Private(&fLanguage).ICULocale(),
|
||||
longFormat ? fLongTimeFormat : fShortTimeFormat);
|
||||
if (timeFormatter.Get() == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
@ -495,10 +569,13 @@ status_t
|
||||
BLocale::FormatTime(BString* string, time_t time, bool longFormat,
|
||||
const BTimeZone* timeZone) const
|
||||
{
|
||||
string->Truncate(0);
|
||||
BAutolock lock(fLock);
|
||||
if (!lock.IsLocked())
|
||||
return B_ERROR;
|
||||
|
||||
ObjectDeleter<DateFormat> timeFormatter = CreateTimeFormat(longFormat,
|
||||
*fICULocale, longFormat ? fLongTimeFormat : fShortTimeFormat);
|
||||
*BLanguage::Private(&fLanguage).ICULocale(),
|
||||
longFormat ? fLongTimeFormat : fShortTimeFormat);
|
||||
if (timeFormatter.Get() == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
@ -513,6 +590,7 @@ BLocale::FormatTime(BString* string, time_t time, bool longFormat,
|
||||
UnicodeString ICUString;
|
||||
ICUString = timeFormatter->format((UDate)time * 1000, ICUString);
|
||||
|
||||
string->Truncate(0);
|
||||
BStringByteSink stringConverter(string);
|
||||
|
||||
ICUString.toUTF8(stringConverter);
|
||||
@ -525,10 +603,13 @@ status_t
|
||||
BLocale::FormatTime(BString* string, int*& fieldPositions, int& fieldCount,
|
||||
time_t time, bool longFormat) const
|
||||
{
|
||||
string->Truncate(0);
|
||||
BAutolock lock(fLock);
|
||||
if (!lock.IsLocked())
|
||||
return B_ERROR;
|
||||
|
||||
ObjectDeleter<DateFormat> timeFormatter = CreateTimeFormat(longFormat,
|
||||
*fICULocale, longFormat ? fLongTimeFormat : fShortTimeFormat);
|
||||
*BLanguage::Private(&fLanguage).ICULocale(),
|
||||
longFormat ? fLongTimeFormat : fShortTimeFormat);
|
||||
if (timeFormatter.Get() == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
@ -556,6 +637,7 @@ BLocale::FormatTime(BString* string, int*& fieldPositions, int& fieldCount,
|
||||
for (int i = 0 ; i < fieldCount ; i++ )
|
||||
fieldPositions[i] = fieldPosStorage[i];
|
||||
|
||||
string->Truncate(0);
|
||||
BStringByteSink stringConverter(string);
|
||||
|
||||
ICUString.toUTF8(stringConverter);
|
||||
@ -568,8 +650,13 @@ status_t
|
||||
BLocale::GetTimeFields(BDateElement*& fields, int& fieldCount,
|
||||
bool longFormat) const
|
||||
{
|
||||
BAutolock lock(fLock);
|
||||
if (!lock.IsLocked())
|
||||
return B_ERROR;
|
||||
|
||||
ObjectDeleter<DateFormat> timeFormatter = CreateTimeFormat(longFormat,
|
||||
*fICULocale, longFormat ? fLongTimeFormat : fShortTimeFormat);
|
||||
*BCountry::Private(&fCountry).ICULocale(),
|
||||
longFormat ? fLongTimeFormat : fShortTimeFormat);
|
||||
if (timeFormatter.Get() == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
@ -624,6 +711,10 @@ BLocale::GetTimeFields(BDateElement*& fields, int& fieldCount,
|
||||
status_t
|
||||
BLocale::SetTimeFormat(const char* formatString, bool longFormat)
|
||||
{
|
||||
BAutolock lock(fLock);
|
||||
if (!lock.IsLocked())
|
||||
return B_ERROR;
|
||||
|
||||
if (longFormat)
|
||||
fLongTimeFormat = formatString;
|
||||
else
|
||||
@ -636,6 +727,10 @@ BLocale::SetTimeFormat(const char* formatString, bool longFormat)
|
||||
status_t
|
||||
BLocale::GetTimeFormat(BString& format, bool longFormat) const
|
||||
{
|
||||
BAutolock lock(fLock);
|
||||
if (!lock.IsLocked())
|
||||
return B_ERROR;
|
||||
|
||||
if (longFormat && fLongTimeFormat.Length() > 0)
|
||||
format = fLongTimeFormat;
|
||||
else if (!longFormat && fShortTimeFormat.Length() > 0)
|
||||
@ -644,7 +739,8 @@ BLocale::GetTimeFormat(BString& format, bool longFormat) const
|
||||
format.Truncate(0);
|
||||
|
||||
ObjectDeleter<DateFormat> timeFormatter = CreateTimeFormat(longFormat,
|
||||
*fICULocale, longFormat ? fLongTimeFormat : fShortTimeFormat);
|
||||
*BCountry::Private(&fCountry).ICULocale(),
|
||||
longFormat ? fLongTimeFormat : fShortTimeFormat);
|
||||
if (timeFormatter.Get() == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
@ -662,6 +758,20 @@ BLocale::GetTimeFormat(BString& format, bool longFormat) const
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BLocale::_UpdateFormats()
|
||||
{
|
||||
FetchDateFormat(true, *BCountry::Private(&fCountry).ICULocale(),
|
||||
this->fLongDateFormat);
|
||||
FetchDateFormat(false, *BCountry::Private(&fCountry).ICULocale(),
|
||||
this->fShortDateFormat);
|
||||
FetchTimeFormat(true, *BCountry::Private(&fCountry).ICULocale(),
|
||||
this->fLongTimeFormat);
|
||||
FetchTimeFormat(false, *BCountry::Private(&fCountry).ICULocale(),
|
||||
this->fShortTimeFormat);
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - Numbers
|
||||
|
||||
|
||||
@ -680,9 +790,14 @@ BLocale::FormatNumber(char* string, size_t maxSize, double value) const
|
||||
status_t
|
||||
BLocale::FormatNumber(BString* string, double value) const
|
||||
{
|
||||
BAutolock lock(fLock);
|
||||
if (!lock.IsLocked())
|
||||
return B_ERROR;
|
||||
|
||||
UErrorCode err = U_ZERO_ERROR;
|
||||
ObjectDeleter<NumberFormat> numberFormatter = NumberFormat::createInstance(
|
||||
*fICULocale, NumberFormat::kNumberStyle, err);
|
||||
*BCountry::Private(&fCountry).ICULocale(), NumberFormat::kNumberStyle,
|
||||
err);
|
||||
|
||||
if (numberFormatter.Get() == NULL)
|
||||
return B_NO_MEMORY;
|
||||
@ -715,9 +830,14 @@ BLocale::FormatNumber(char* string, size_t maxSize, int32 value) const
|
||||
status_t
|
||||
BLocale::FormatNumber(BString* string, int32 value) const
|
||||
{
|
||||
BAutolock lock(fLock);
|
||||
if (!lock.IsLocked())
|
||||
return B_ERROR;
|
||||
|
||||
UErrorCode err = U_ZERO_ERROR;
|
||||
ObjectDeleter<NumberFormat> numberFormatter = NumberFormat::createInstance(
|
||||
*fICULocale, NumberFormat::kNumberStyle, err);
|
||||
*BCountry::Private(&fCountry).ICULocale(), NumberFormat::kNumberStyle,
|
||||
err);
|
||||
|
||||
if (numberFormatter.Get() == NULL)
|
||||
return B_NO_MEMORY;
|
||||
@ -753,9 +873,14 @@ BLocale::FormatMonetary(BString* string, double value) const
|
||||
if (string == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
BAutolock lock(fLock);
|
||||
if (!lock.IsLocked())
|
||||
return B_ERROR;
|
||||
|
||||
UErrorCode err;
|
||||
ObjectDeleter<NumberFormat> numberFormatter
|
||||
= NumberFormat::createCurrencyInstance(*fICULocale, err);
|
||||
= NumberFormat::createCurrencyInstance(
|
||||
*BCountry::Private(&fCountry).ICULocale(), err);
|
||||
|
||||
if (numberFormatter.Get() == NULL)
|
||||
return B_NO_MEMORY;
|
||||
@ -777,14 +902,17 @@ status_t
|
||||
BLocale::FormatMonetary(BString* string, int*& fieldPositions,
|
||||
BNumberElement*& fieldTypes, int& fieldCount, double value) const
|
||||
{
|
||||
BAutolock lock(fLock);
|
||||
if (!lock.IsLocked())
|
||||
return B_ERROR;
|
||||
|
||||
UErrorCode err = U_ZERO_ERROR;
|
||||
ObjectDeleter<NumberFormat> numberFormatter
|
||||
= NumberFormat::createCurrencyInstance(*fICULocale, err);
|
||||
= NumberFormat::createCurrencyInstance(
|
||||
*BCountry::Private(&fCountry).ICULocale(), err);
|
||||
if (U_FAILURE(err))
|
||||
return B_NO_MEMORY;
|
||||
|
||||
string->Truncate(0);
|
||||
|
||||
fieldPositions = NULL;
|
||||
fieldTypes = NULL;
|
||||
ICU_VERSION::FieldPositionIterator positionIterator;
|
||||
@ -827,6 +955,7 @@ BLocale::FormatMonetary(BString* string, int*& fieldPositions,
|
||||
}
|
||||
}
|
||||
|
||||
string->Truncate(0);
|
||||
BStringByteSink stringConverter(string);
|
||||
|
||||
ICUString.toUTF8(stringConverter);
|
||||
@ -838,9 +967,13 @@ BLocale::FormatMonetary(BString* string, int*& fieldPositions,
|
||||
status_t
|
||||
BLocale::GetCurrencySymbol(BString& result) const
|
||||
{
|
||||
BAutolock lock(fLock);
|
||||
if (!lock.IsLocked())
|
||||
return B_ERROR;
|
||||
|
||||
UErrorCode error = U_ZERO_ERROR;
|
||||
NumberFormat* format = NumberFormat::createCurrencyInstance(*fICULocale,
|
||||
error);
|
||||
NumberFormat* format = NumberFormat::createCurrencyInstance(
|
||||
*BCountry::Private(&fCountry).ICULocale(), error);
|
||||
|
||||
if (U_FAILURE(error))
|
||||
return B_ERROR;
|
||||
@ -860,11 +993,10 @@ BLocale::GetCurrencySymbol(BString& result) const
|
||||
|
||||
|
||||
static DateFormat*
|
||||
CreateDateFormat(bool longFormat, const Locale& locale,
|
||||
const BString& format)
|
||||
CreateDateFormat(bool longFormat, const Locale& locale, const BString& format)
|
||||
{
|
||||
DateFormat* dateFormatter = DateFormat::createDateInstance(
|
||||
longFormat ? DateFormat::FULL : DateFormat::SHORT, locale);
|
||||
longFormat ? DateFormat::kFull : DateFormat::kShort, locale);
|
||||
|
||||
if (format.Length() > 0) {
|
||||
SimpleDateFormat* dateFormatterImpl
|
||||
@ -879,11 +1011,10 @@ CreateDateFormat(bool longFormat, const Locale& locale,
|
||||
|
||||
|
||||
static DateFormat*
|
||||
CreateTimeFormat(bool longFormat, const Locale& locale,
|
||||
const BString& format)
|
||||
CreateTimeFormat(bool longFormat, const Locale& locale, const BString& format)
|
||||
{
|
||||
DateFormat* timeFormatter = DateFormat::createTimeInstance(
|
||||
longFormat ? DateFormat::MEDIUM : DateFormat::SHORT, locale);
|
||||
longFormat ? DateFormat::kMedium: DateFormat::kShort, locale);
|
||||
|
||||
if (format.Length() > 0) {
|
||||
SimpleDateFormat* timeFormatterImpl
|
||||
@ -895,3 +1026,37 @@ CreateTimeFormat(bool longFormat, const Locale& locale,
|
||||
|
||||
return timeFormatter;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
FetchDateFormat(bool longFormat, const Locale& locale, BString& format)
|
||||
{
|
||||
DateFormat* dateFormatter = DateFormat::createDateInstance(
|
||||
longFormat ? DateFormat::kFull : DateFormat::kShort, locale);
|
||||
|
||||
SimpleDateFormat* dateFormatterImpl
|
||||
= static_cast<SimpleDateFormat*>(dateFormatter);
|
||||
|
||||
UnicodeString pattern;
|
||||
dateFormatterImpl->toPattern(pattern);
|
||||
format.Truncate(0);
|
||||
BStringByteSink stringConverter(&format);
|
||||
pattern.toUTF8(stringConverter);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
FetchTimeFormat(bool longFormat, const Locale& locale, BString& format)
|
||||
{
|
||||
DateFormat* timeFormatter = DateFormat::createTimeInstance(
|
||||
longFormat ? DateFormat::kMedium : DateFormat::kShort, locale);
|
||||
|
||||
SimpleDateFormat* timeFormatterImpl
|
||||
= static_cast<SimpleDateFormat*>(timeFormatter);
|
||||
|
||||
UnicodeString pattern;
|
||||
timeFormatterImpl->toPattern(pattern);
|
||||
format.Truncate(0);
|
||||
BStringByteSink stringConverter(&format);
|
||||
pattern.toUTF8(stringConverter);
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#include <Autolock.h>
|
||||
#include <AppFileInfo.h>
|
||||
#include <Bitmap.h>
|
||||
#include <Catalog.h>
|
||||
#include <Collator.h>
|
||||
#include <Country.h>
|
||||
@ -24,6 +25,7 @@
|
||||
#include <Directory.h>
|
||||
#include <Entry.h>
|
||||
#include <File.h>
|
||||
#include <IconUtils.h>
|
||||
#include <Language.h>
|
||||
#include <Locale.h>
|
||||
#include <MutableLocaleRoster.h>
|
||||
@ -227,6 +229,39 @@ BLocaleRoster::GetAvailableTimeZonesForCountry(BMessage* timeZones,
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BLocaleRoster::GetFlagIconForCountry(BBitmap* flagIcon, const char* countryCode)
|
||||
{
|
||||
if (countryCode == NULL)
|
||||
return B_BAD_DATA;
|
||||
|
||||
BAutolock lock(gRosterData.fLock);
|
||||
if (!lock.IsLocked())
|
||||
return B_ERROR;
|
||||
|
||||
if (!gRosterData.fAreResourcesLoaded) {
|
||||
status_t result = gRosterData.fResources.SetToImage(&gRosterData);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
result = gRosterData.fResources.PreloadResourceType();
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
gRosterData.fAreResourcesLoaded = true;
|
||||
}
|
||||
|
||||
size_t size;
|
||||
const void* buffer = gRosterData.fResources.LoadResource(B_VECTOR_ICON_TYPE,
|
||||
countryCode, &size);
|
||||
if (buffer == NULL || size == 0)
|
||||
return B_NAME_NOT_FOUND;
|
||||
|
||||
return BIconUtils::GetVectorIcon(static_cast<const uint8*>(buffer), size,
|
||||
flagIcon);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BLocaleRoster::GetInstalledCatalogs(BMessage* languageList,
|
||||
const char* sigPattern, const char* langPattern, int32 fingerprint) const
|
||||
|
@ -122,7 +122,7 @@ CatalogAddOnInfo::UnloadIfPossible()
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - MutableLocaleRoster
|
||||
// #pragma mark - RosterData
|
||||
|
||||
|
||||
RosterData gRosterData;
|
||||
@ -132,7 +132,8 @@ static const char* kPriorityAttr = "ADDON:priority";
|
||||
|
||||
RosterData::RosterData()
|
||||
:
|
||||
fLock("LocaleRosterData")
|
||||
fLock("LocaleRosterData"),
|
||||
fAreResourcesLoaded(false)
|
||||
{
|
||||
openlog_team("liblocale.so", LOG_PID, LOG_USER);
|
||||
#ifndef DEBUG
|
||||
@ -439,8 +440,10 @@ RosterData::_LoadLocaleSettings()
|
||||
BString codeName;
|
||||
BLocale newDefaultLocale;
|
||||
|
||||
if (settings.FindString("country", &codeName) == B_OK)
|
||||
newDefaultLocale = BLocale(codeName);
|
||||
if (settings.FindString("country", &codeName) == B_OK) {
|
||||
BCountry country(codeName);
|
||||
newDefaultLocale = BLocale(NULL, &country);
|
||||
}
|
||||
|
||||
BString timeFormat;
|
||||
if (settings.FindString("shortTimeFormat", &timeFormat) == B_OK)
|
||||
@ -461,7 +464,8 @@ RosterData::_LoadLocaleSettings()
|
||||
|
||||
fPreferredLanguages.MakeEmpty();
|
||||
fPreferredLanguages.AddString("language", "en");
|
||||
_SetDefaultLocale("en_US");
|
||||
BLanguage defaultLanguage("en_US");
|
||||
_SetDefaultLocale(BLocale(&defaultLanguage));
|
||||
|
||||
return status;
|
||||
}
|
||||
@ -574,7 +578,9 @@ RosterData::_SetDefaultLocale(const BLocale& newLocale)
|
||||
fDefaultLocale = newLocale;
|
||||
|
||||
UErrorCode icuError = U_ZERO_ERROR;
|
||||
Locale icuLocale = Locale::createCanonical(newLocale.Code());
|
||||
BCountry defaultCountry;
|
||||
newLocale.GetCountry(&defaultCountry);
|
||||
Locale icuLocale = Locale::createCanonical(defaultCountry.Code());
|
||||
if (icuLocale.isBogus())
|
||||
return B_ERROR;
|
||||
|
||||
@ -607,7 +613,7 @@ RosterData::_SetPreferredLanguages(const BMessage* languages)
|
||||
if (languages != NULL
|
||||
&& languages->FindString("language", &langName) == B_OK) {
|
||||
fDefaultLocale.SetCollator(BCollator(langName.String()));
|
||||
fDefaultLocale.SetLanguage(langName.String());
|
||||
fDefaultLocale.SetLanguage(BLanguage(langName.String()));
|
||||
|
||||
fPreferredLanguages.RemoveName("language");
|
||||
for (int i = 0; languages->FindString("language", i, &langName) == B_OK;
|
||||
@ -627,7 +633,9 @@ RosterData::_SetPreferredLanguages(const BMessage* languages)
|
||||
status_t
|
||||
RosterData::_AddDefaultCountryToMessage(BMessage* message) const
|
||||
{
|
||||
status_t status = message->AddString("country", fDefaultLocale.Code());
|
||||
BCountry defaultCountry;
|
||||
fDefaultLocale.GetCountry(&defaultCountry);
|
||||
status_t status = message->AddString("country", defaultCountry.Code());
|
||||
BString timeFormat;
|
||||
if (status == B_OK)
|
||||
status = fDefaultLocale.GetTimeFormat(timeFormat, false);
|
||||
|
@ -38,8 +38,8 @@ static const uint32 skOffsetFromGMTField = 1U << 8;
|
||||
|
||||
BTimeZone::BTimeZone(const char* zoneID, const BLanguage* language)
|
||||
:
|
||||
fIcuTimeZone(NULL),
|
||||
fIcuLocale(NULL),
|
||||
fICUTimeZone(NULL),
|
||||
fICULocale(NULL),
|
||||
fInitStatus(B_NO_INIT),
|
||||
fInitializedFields(0)
|
||||
{
|
||||
@ -49,12 +49,12 @@ BTimeZone::BTimeZone(const char* zoneID, const BLanguage* language)
|
||||
|
||||
BTimeZone::BTimeZone(const BTimeZone& other)
|
||||
:
|
||||
fIcuTimeZone(other.fIcuTimeZone == NULL
|
||||
fICUTimeZone(other.fICUTimeZone == NULL
|
||||
? NULL
|
||||
: other.fIcuTimeZone->clone()),
|
||||
fIcuLocale(other.fIcuLocale == NULL
|
||||
: other.fICUTimeZone->clone()),
|
||||
fICULocale(other.fICULocale == NULL
|
||||
? NULL
|
||||
: other.fIcuLocale->clone()),
|
||||
: other.fICULocale->clone()),
|
||||
fInitStatus(other.fInitStatus),
|
||||
fInitializedFields(other.fInitializedFields),
|
||||
fZoneID(other.fZoneID),
|
||||
@ -70,20 +70,20 @@ BTimeZone::BTimeZone(const BTimeZone& other)
|
||||
|
||||
BTimeZone::~BTimeZone()
|
||||
{
|
||||
delete fIcuLocale;
|
||||
delete fIcuTimeZone;
|
||||
delete fICULocale;
|
||||
delete fICUTimeZone;
|
||||
}
|
||||
|
||||
|
||||
BTimeZone& BTimeZone::operator=(const BTimeZone& source)
|
||||
{
|
||||
delete fIcuTimeZone;
|
||||
fIcuTimeZone = source.fIcuTimeZone == NULL
|
||||
delete fICUTimeZone;
|
||||
fICUTimeZone = source.fICUTimeZone == NULL
|
||||
? NULL
|
||||
: source.fIcuTimeZone->clone();
|
||||
fIcuLocale = source.fIcuLocale == NULL
|
||||
: source.fICUTimeZone->clone();
|
||||
fICULocale = source.fICULocale == NULL
|
||||
? NULL
|
||||
: source.fIcuLocale->clone();
|
||||
: source.fICULocale->clone();
|
||||
fInitStatus = source.fInitStatus;
|
||||
fInitializedFields = source.fInitializedFields;
|
||||
fZoneID = source.fZoneID;
|
||||
@ -110,11 +110,11 @@ BTimeZone::Name() const
|
||||
{
|
||||
if ((fInitializedFields & skNameField) == 0) {
|
||||
UnicodeString unicodeString;
|
||||
if (fIcuLocale != NULL) {
|
||||
fIcuTimeZone->getDisplayName(false, TimeZone::GENERIC_LOCATION,
|
||||
*fIcuLocale, unicodeString);
|
||||
if (fICULocale != NULL) {
|
||||
fICUTimeZone->getDisplayName(false, TimeZone::GENERIC_LOCATION,
|
||||
*fICULocale, unicodeString);
|
||||
} else {
|
||||
fIcuTimeZone->getDisplayName(false, TimeZone::GENERIC_LOCATION,
|
||||
fICUTimeZone->getDisplayName(false, TimeZone::GENERIC_LOCATION,
|
||||
unicodeString);
|
||||
}
|
||||
BStringByteSink sink(&fName);
|
||||
@ -131,11 +131,11 @@ BTimeZone::DaylightSavingName() const
|
||||
{
|
||||
if ((fInitializedFields & skDaylightSavingNameField) == 0) {
|
||||
UnicodeString unicodeString;
|
||||
if (fIcuLocale != NULL) {
|
||||
fIcuTimeZone->getDisplayName(true, TimeZone::GENERIC_LOCATION,
|
||||
*fIcuLocale, unicodeString);
|
||||
if (fICULocale != NULL) {
|
||||
fICUTimeZone->getDisplayName(true, TimeZone::GENERIC_LOCATION,
|
||||
*fICULocale, unicodeString);
|
||||
} else {
|
||||
fIcuTimeZone->getDisplayName(true, TimeZone::GENERIC_LOCATION,
|
||||
fICUTimeZone->getDisplayName(true, TimeZone::GENERIC_LOCATION,
|
||||
unicodeString);
|
||||
}
|
||||
BStringByteSink sink(&fDaylightSavingName);
|
||||
@ -152,11 +152,11 @@ BTimeZone::ShortName() const
|
||||
{
|
||||
if ((fInitializedFields & skShortNameField) == 0) {
|
||||
UnicodeString unicodeString;
|
||||
if (fIcuLocale != NULL) {
|
||||
fIcuTimeZone->getDisplayName(false, TimeZone::SHORT_COMMONLY_USED,
|
||||
*fIcuLocale, unicodeString);
|
||||
if (fICULocale != NULL) {
|
||||
fICUTimeZone->getDisplayName(false, TimeZone::SHORT_COMMONLY_USED,
|
||||
*fICULocale, unicodeString);
|
||||
} else {
|
||||
fIcuTimeZone->getDisplayName(false, TimeZone::SHORT_COMMONLY_USED,
|
||||
fICUTimeZone->getDisplayName(false, TimeZone::SHORT_COMMONLY_USED,
|
||||
unicodeString);
|
||||
}
|
||||
BStringByteSink sink(&fShortName);
|
||||
@ -173,11 +173,11 @@ BTimeZone::ShortDaylightSavingName() const
|
||||
{
|
||||
if ((fInitializedFields & skShortDaylightSavingNameField) == 0) {
|
||||
UnicodeString unicodeString;
|
||||
if (fIcuLocale != NULL) {
|
||||
fIcuTimeZone->getDisplayName(true, TimeZone::SHORT_COMMONLY_USED,
|
||||
*fIcuLocale, unicodeString);
|
||||
if (fICULocale != NULL) {
|
||||
fICUTimeZone->getDisplayName(true, TimeZone::SHORT_COMMONLY_USED,
|
||||
*fICULocale, unicodeString);
|
||||
} else {
|
||||
fIcuTimeZone->getDisplayName(true, TimeZone::SHORT_COMMONLY_USED,
|
||||
fICUTimeZone->getDisplayName(true, TimeZone::SHORT_COMMONLY_USED,
|
||||
unicodeString);
|
||||
}
|
||||
BStringByteSink sink(&fShortDaylightSavingName);
|
||||
@ -198,7 +198,7 @@ BTimeZone::OffsetFromGMT() const
|
||||
UDate nowMillis = 1000 * (double)time(NULL);
|
||||
|
||||
UErrorCode error = U_ZERO_ERROR;
|
||||
fIcuTimeZone->getOffset(nowMillis, FALSE, rawOffset, dstOffset, error);
|
||||
fICUTimeZone->getOffset(nowMillis, FALSE, rawOffset, dstOffset, error);
|
||||
if (!U_SUCCESS(error))
|
||||
fOffsetFromGMT = 0;
|
||||
else {
|
||||
@ -216,7 +216,7 @@ bool
|
||||
BTimeZone::SupportsDaylightSaving() const
|
||||
{
|
||||
if ((fInitializedFields & skSupportsDaylightSavingField) == 0) {
|
||||
fSupportsDaylightSaving = fIcuTimeZone->useDaylightTime();
|
||||
fSupportsDaylightSaving = fICUTimeZone->useDaylightTime();
|
||||
fInitializedFields |= skSupportsDaylightSavingField;
|
||||
}
|
||||
|
||||
@ -241,31 +241,31 @@ BTimeZone::SetLanguage(const BLanguage* language)
|
||||
status_t
|
||||
BTimeZone::SetTo(const char* zoneID, const BLanguage* language)
|
||||
{
|
||||
delete fIcuLocale;
|
||||
fIcuLocale = NULL;
|
||||
delete fIcuTimeZone;
|
||||
delete fICULocale;
|
||||
fICULocale = NULL;
|
||||
delete fICUTimeZone;
|
||||
fInitializedFields = 0;
|
||||
|
||||
if (zoneID == NULL || zoneID[0] == '\0')
|
||||
fIcuTimeZone = TimeZone::createDefault();
|
||||
fICUTimeZone = TimeZone::createDefault();
|
||||
else
|
||||
fIcuTimeZone = TimeZone::createTimeZone(zoneID);
|
||||
fICUTimeZone = TimeZone::createTimeZone(zoneID);
|
||||
|
||||
if (fIcuTimeZone == NULL) {
|
||||
if (fICUTimeZone == NULL) {
|
||||
fInitStatus = B_NAME_NOT_FOUND;
|
||||
return fInitStatus;
|
||||
}
|
||||
|
||||
if (language != NULL) {
|
||||
fIcuLocale = new Locale(language->Code());
|
||||
if (fIcuLocale == NULL) {
|
||||
fICULocale = new Locale(language->Code());
|
||||
if (fICULocale == NULL) {
|
||||
fInitStatus = B_NO_MEMORY;
|
||||
return fInitStatus;
|
||||
}
|
||||
}
|
||||
|
||||
UnicodeString unicodeString;
|
||||
fIcuTimeZone->getID(unicodeString);
|
||||
fICUTimeZone->getID(unicodeString);
|
||||
BStringByteSink sink(&fZoneID);
|
||||
unicodeString.toUTF8(sink);
|
||||
|
||||
|
@ -50,12 +50,12 @@ public:
|
||||
:
|
||||
BMenuItem(label, _MenuMessage(code, field))
|
||||
{
|
||||
fIcuCode = code;
|
||||
fICUCode = code;
|
||||
}
|
||||
|
||||
const BString& ICUCode() const
|
||||
{
|
||||
return fIcuCode;
|
||||
return fICUCode;
|
||||
}
|
||||
|
||||
private:
|
||||
@ -69,7 +69,7 @@ private:
|
||||
}
|
||||
|
||||
private:
|
||||
BString fIcuCode;
|
||||
BString fICUCode;
|
||||
};
|
||||
|
||||
|
||||
@ -414,32 +414,33 @@ FormatView::MessageReceived(BMessage* message)
|
||||
menuField->MenuItem()->SetLabel(menuItem->Label());
|
||||
|
||||
_UpdateLongDateFormatString();
|
||||
// fall through
|
||||
}
|
||||
// pass trough
|
||||
|
||||
case kSettingsContentsModified:
|
||||
{
|
||||
int32 separator = 0;
|
||||
BMenuItem* item = fSeparatorMenuField->Menu()->FindMarked();
|
||||
if (item) {
|
||||
separator = fSeparatorMenuField->Menu()->IndexOf(item);
|
||||
if (separator >= 0)
|
||||
// settings.SetTimeFormatSeparator(
|
||||
// (FormatSeparator)separator);
|
||||
;
|
||||
}
|
||||
|
||||
// Make the notification message and send it to the tracker:
|
||||
BMessage notificationMessage;
|
||||
notificationMessage.AddInt32("TimeFormatSeparator", separator);
|
||||
notificationMessage.AddBool("24HrClock",
|
||||
f24HrRadioButton->Value() == 1);
|
||||
|
||||
_UpdateExamples();
|
||||
|
||||
Window()->PostMessage(kSettingsContentsModified);
|
||||
break;
|
||||
{
|
||||
int32 separator = 0;
|
||||
BMenuItem* item = fSeparatorMenuField->Menu()->FindMarked();
|
||||
if (item) {
|
||||
separator = fSeparatorMenuField->Menu()->IndexOf(item);
|
||||
if (separator >= 0)
|
||||
// settings.SetTimeFormatSeparator(
|
||||
// (FormatSeparator)separator);
|
||||
;
|
||||
}
|
||||
|
||||
// Make the notification message and send it to the tracker:
|
||||
BMessage notificationMessage;
|
||||
notificationMessage.AddInt32("TimeFormatSeparator", separator);
|
||||
notificationMessage.AddBool("24HrClock",
|
||||
f24HrRadioButton->Value() == 1);
|
||||
|
||||
_UpdateExamples();
|
||||
|
||||
Window()->PostMessage(kSettingsContentsModified);
|
||||
break;
|
||||
}
|
||||
|
||||
case kClockFormatChange:
|
||||
{
|
||||
BMessage newMessage(kMsgSettingsChanged);
|
||||
@ -492,39 +493,6 @@ FormatView::MessageReceived(BMessage* message)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FormatView::SetDefaults()
|
||||
{
|
||||
/*
|
||||
TrackerSettings settings;
|
||||
|
||||
settings.SetTimeFormatSeparator(kSlashSeparator);
|
||||
settings.SetDateOrderFormat(kMDYFormat);
|
||||
settings.SetClockTo24Hr(false);
|
||||
*/
|
||||
|
||||
fLocale = *be_locale;
|
||||
// We work on a copy of the default country and set the changes when
|
||||
// closing the preflet
|
||||
_UpdateExamples();
|
||||
_SendNotices();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FormatView::IsDefaultable() const
|
||||
{
|
||||
/*
|
||||
TrackerSettings settings;
|
||||
|
||||
return settings.TimeFormatSeparator() != kSlashSeparator
|
||||
|| settings.DateOrderFormat() != kMDYFormat
|
||||
|| settings.ClockIs24Hr() != false;
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FormatView::Revert()
|
||||
{
|
||||
@ -692,7 +660,6 @@ FormatView::_ParseCurrencyFormat()
|
||||
void
|
||||
FormatView::_ParseDateFormat()
|
||||
{
|
||||
// TODO parse the short date too
|
||||
BString dateFormatString;
|
||||
fLocale.GetDateFormat(dateFormatString, true);
|
||||
const char* dateFormat = dateFormatString.String();
|
||||
@ -704,7 +671,8 @@ FormatView::_ParseDateFormat()
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
fieldBegin = parsePointer;
|
||||
while (*parsePointer == *(parsePointer + 1)) parsePointer++ ;
|
||||
while (*parsePointer == *(parsePointer + 1))
|
||||
parsePointer++;
|
||||
parsePointer++;
|
||||
BString str;
|
||||
str.Append(fieldBegin, parsePointer - fieldBegin);
|
||||
@ -731,11 +699,13 @@ FormatView::_ParseDateFormat()
|
||||
fLongDateMenu[i]->MenuItem()->SetLabel(str.Append("*"));
|
||||
|
||||
fieldBegin = parsePointer;
|
||||
while ((!IsSpecialDateChar(*parsePointer)) && *parsePointer != '\0'
|
||||
&& *(parsePointer - 1) >= 0) {
|
||||
while ((!IsSpecialDateChar(*parsePointer)) && *parsePointer != '\0') {
|
||||
if (*parsePointer == '\'') {
|
||||
parsePointer++;
|
||||
while (*parsePointer != '\'') parsePointer++;
|
||||
while (*parsePointer != '\0' && *parsePointer != '\'')
|
||||
parsePointer++;
|
||||
if (*parsePointer == '\0')
|
||||
break;
|
||||
}
|
||||
parsePointer++;
|
||||
}
|
||||
@ -754,7 +724,8 @@ FormatView::_ParseDateFormat()
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
fieldBegin = parsePointer;
|
||||
while (*parsePointer == *(parsePointer + 1)) parsePointer++ ;
|
||||
while (*parsePointer == *(parsePointer + 1))
|
||||
parsePointer++;
|
||||
parsePointer++;
|
||||
BString str;
|
||||
str.Append(fieldBegin, parsePointer - fieldBegin);
|
||||
@ -783,11 +754,13 @@ FormatView::_ParseDateFormat()
|
||||
}
|
||||
|
||||
fieldBegin = parsePointer;
|
||||
while ((!IsSpecialDateChar(*parsePointer)) && *parsePointer != '\0'
|
||||
&& *(parsePointer - 1) >= 0) {
|
||||
while ((!IsSpecialDateChar(*parsePointer)) && *parsePointer != '\0') {
|
||||
if (*parsePointer == '\'') {
|
||||
parsePointer++;
|
||||
while (*parsePointer != '\'') parsePointer++;
|
||||
while (*parsePointer != '\0' && *parsePointer != '\'')
|
||||
parsePointer++;
|
||||
if (*parsePointer == '\0')
|
||||
break;
|
||||
}
|
||||
parsePointer++;
|
||||
}
|
||||
|
@ -43,8 +43,6 @@ public:
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
virtual void AttachedToWindow();
|
||||
|
||||
virtual void SetDefaults();
|
||||
virtual bool IsDefaultable() const;
|
||||
virtual void Revert();
|
||||
virtual void SetLocale(const BLocale& locale);
|
||||
virtual void RecordRevertSettings();
|
||||
|
@ -89,9 +89,9 @@ LanguageListItem::DrawItem(BView* owner, BRect frame, bool complete)
|
||||
owner->SetHighColor(kBlack);
|
||||
else {
|
||||
owner->SetHighColor(tint_color(owner->LowColor(), B_DARKEN_3_TINT));
|
||||
text += " (";
|
||||
text += " [";
|
||||
text += B_TRANSLATE("already chosen");
|
||||
text += ")";
|
||||
text += "]";
|
||||
}
|
||||
|
||||
BFont font = be_plain_font;
|
||||
|
@ -67,6 +67,8 @@ LocaleSettings::UpdateFrom(BMessage* message)
|
||||
{
|
||||
BString messageContent;
|
||||
|
||||
BLocale locale(*be_locale);
|
||||
|
||||
if (message->FindString("language", &messageContent) == B_OK) {
|
||||
fMessage.RemoveName("language");
|
||||
|
||||
@ -78,30 +80,29 @@ LocaleSettings::UpdateFrom(BMessage* message)
|
||||
gMutableLocaleRoster->SetPreferredLanguages(message);
|
||||
}
|
||||
|
||||
BLocale locale(*be_locale);
|
||||
bool countryChanged = false;
|
||||
bool localeChanged = false;
|
||||
if (message->FindString("country", &messageContent) == B_OK) {
|
||||
fMessage.ReplaceString("country", messageContent);
|
||||
fMessage.RemoveName("shortTimeFormat");
|
||||
fMessage.RemoveName("longTimeFormat");
|
||||
locale = BLocale(messageContent.String());
|
||||
countryChanged = true;
|
||||
locale.SetCountry(messageContent.String());
|
||||
localeChanged = true;
|
||||
}
|
||||
|
||||
if (message->FindString("shortTimeFormat", &messageContent) == B_OK) {
|
||||
fMessage.RemoveName("shortTimeFormat");
|
||||
fMessage.AddString("shortTimeFormat", messageContent);
|
||||
locale.SetTimeFormat(messageContent, false);
|
||||
countryChanged = true;
|
||||
localeChanged = true;
|
||||
}
|
||||
|
||||
if (message->FindString("longTimeFormat", &messageContent) == B_OK) {
|
||||
fMessage.RemoveName("longTimeFormat");
|
||||
fMessage.AddString("longTimeFormat", messageContent);
|
||||
locale.SetTimeFormat(messageContent, true);
|
||||
countryChanged = true;
|
||||
localeChanged = true;
|
||||
}
|
||||
|
||||
if (countryChanged)
|
||||
if (localeChanged)
|
||||
gMutableLocaleRoster->SetDefaultLocale(locale);
|
||||
}
|
||||
|
@ -29,6 +29,9 @@
|
||||
#include "LanguageListView.h"
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#undef B_TRANSLATE_CONTEXT
|
||||
#define B_TRANSLATE_CONTEXT "Locale Preflet Window"
|
||||
|
||||
@ -94,6 +97,9 @@ LocaleWindow::LocaleWindow()
|
||||
fLanguageListView->SetInvocationMessage(new BMessage(kMsgLanguageInvoked));
|
||||
fLanguageListView->SetDragMessage(new BMessage(kMsgLanguageDragged));
|
||||
|
||||
BFont font;
|
||||
fLanguageListView->GetFont(&font);
|
||||
|
||||
// Fill the language list from the LocaleRoster data
|
||||
BMessage installedLanguages;
|
||||
if (be_locale_roster->GetInstalledLanguages(&installedLanguages) == B_OK) {
|
||||
@ -102,40 +108,37 @@ LocaleWindow::LocaleWindow()
|
||||
|
||||
for (int i = 0; installedLanguages.FindString("langs", i, ¤tID)
|
||||
== B_OK; i++) {
|
||||
// Now get an human-readable, localized name for each language
|
||||
BLanguage* currentLanguage;
|
||||
be_locale_roster->GetLanguage(currentID.String(),
|
||||
¤tLanguage);
|
||||
|
||||
// Now get the human-readable, native name for each language
|
||||
BString name;
|
||||
currentLanguage->GetName(name);
|
||||
BLanguage currentLanguage(currentID.String());
|
||||
currentLanguage.GetNativeName(name);
|
||||
|
||||
// TODO: as long as the app_server doesn't support font overlays,
|
||||
// use the translated name if problematic characters are used...
|
||||
const char* string = name.String();
|
||||
while (uint32 code = BUnicodeChar::FromUTF8(&string)) {
|
||||
if (code > 1424) {
|
||||
currentLanguage->GetTranslatedName(name);
|
||||
// TODO: the following block fails to detect a couple of language
|
||||
// names as containing glyphs we can't render. Why's that?
|
||||
bool hasGlyphs[name.CountChars()];
|
||||
font.GetHasGlyphs(name.String(), name.CountChars(), hasGlyphs);
|
||||
for (int32 i = 0; i < name.CountChars(); ++i) {
|
||||
if (!hasGlyphs[i]) {
|
||||
// replace by name translated to current language
|
||||
currentLanguage.GetName(name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LanguageListItem* item = new LanguageListItem(name,
|
||||
currentID.String(), currentLanguage->Code());
|
||||
if (currentLanguage->IsCountrySpecific()
|
||||
currentID.String(), currentLanguage.Code());
|
||||
if (currentLanguage.IsCountrySpecific()
|
||||
&& lastAddedCountryItem != NULL
|
||||
&& lastAddedCountryItem->Code() == item->Code()) {
|
||||
fLanguageListView->AddUnder(item, lastAddedCountryItem);
|
||||
} else {
|
||||
// This is a language variant, add it at top-level
|
||||
fLanguageListView->AddItem(item);
|
||||
if (!currentLanguage->IsCountrySpecific()) {
|
||||
if (!currentLanguage.IsCountrySpecific()) {
|
||||
item->SetExpanded(false);
|
||||
lastAddedCountryItem = item;
|
||||
}
|
||||
}
|
||||
|
||||
delete currentLanguage;
|
||||
}
|
||||
|
||||
fLanguageListView->FullListSortItems(compare_typed_list_items);
|
||||
@ -172,32 +175,31 @@ LocaleWindow::LocaleWindow()
|
||||
.End()
|
||||
.SetInsets(spacing, spacing, spacing, spacing);
|
||||
|
||||
BView* countryTab = new BView(B_TRANSLATE("Country"), B_WILL_DRAW);
|
||||
BView* countryTab = new BView(B_TRANSLATE("Formatting"), B_WILL_DRAW);
|
||||
countryTab->SetLayout(new BGroupLayout(B_VERTICAL, 0));
|
||||
|
||||
BListView* listView = new BListView("country", B_SINGLE_SELECTION_LIST);
|
||||
BListView* listView = new BListView("formatting", B_SINGLE_SELECTION_LIST);
|
||||
scrollView = new BScrollView("scroller", listView,
|
||||
B_WILL_DRAW | B_FRAME_EVENTS, false, true);
|
||||
listView->SetSelectionMessage(new BMessage(kMsgCountrySelection));
|
||||
|
||||
// get all available countries
|
||||
BMessage countryList;
|
||||
be_locale_roster->GetInstalledLanguages(&countryList);
|
||||
BString countryCode;
|
||||
|
||||
// get all available formatting conventions (by language)
|
||||
BString formattingConventionCode;
|
||||
LanguageListItem* currentItem = NULL;
|
||||
for (int i = 0; countryList.FindString("langs", i, &countryCode) == B_OK;
|
||||
i++) {
|
||||
BLocale locale(countryCode);
|
||||
BString countryName;
|
||||
BCountry defaultFormattingConvention;
|
||||
be_locale->GetCountry(&defaultFormattingConvention);
|
||||
for (int i = 0;
|
||||
installedLanguages.FindString("langs", i, &formattingConventionCode)
|
||||
== B_OK; i++) {
|
||||
BCountry formattingConvention(formattingConventionCode);
|
||||
BString formattingConventionName;
|
||||
formattingConvention.GetName(formattingConventionName);
|
||||
|
||||
locale.GetName(countryName);
|
||||
|
||||
LanguageListItem* item
|
||||
= new LanguageListItem(countryName, countryCode,
|
||||
NULL);
|
||||
LanguageListItem* item = new LanguageListItem(formattingConventionName,
|
||||
formattingConventionCode, NULL);
|
||||
listView->AddItem(item);
|
||||
if (!strcmp(countryCode, be_locale->Code()))
|
||||
if (!strcmp(formattingConventionCode,
|
||||
defaultFormattingConvention.Code()))
|
||||
currentItem = item;
|
||||
}
|
||||
|
||||
@ -358,7 +360,8 @@ LocaleWindow::MessageReceived(BMessage* message)
|
||||
be_app_messenger.SendMessage(&newMessage);
|
||||
SettingsChanged();
|
||||
|
||||
BLocale locale(item->ID());
|
||||
BCountry country(item->ID());
|
||||
BLocale locale(NULL, &country);
|
||||
fFormatView->SetLocale(locale);
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user