One more monster commit (sorry ...) concerning the Locale Kit:

* extracted new class BFormattingConventions from BCountry, which
  manages the formatting conventions from a given locale and 
  allows to get/set the four different date/time formats supported
  by ICU-locales as well as number and monetary formats
* overhauled the Locale preflet:
  + drop editing features for all formats, since I don't think
    they do not make much sense to have in a prefs GUI - being
    able to select from the existing locales should be good
    enough. Please note that you can still change the formats
    programmatically in an application.
  + renamed the 'Countries' tab to 'Formatting'
  + the locale formatting conventions list in the 'Formatting'
    tab is now hierarchical for easier access (less scrolling)
  + fixed functionality of 'Revert' and 'Defaults' buttons
  + added support for using the month/day-names of your preferred
    language during date formatting
* adjusted BLocale to ask BFormattingConventions for the current
  formats when formatting dates and times and to offer 4
  different format styles (full, long, medium and short).
* adjust all classes formatting dates/times to pick the 
  appropriate format style
* BLocaleRoster no longer directly archives/unarchives the 
  individual formatting conventions but delegates that to
  BFormattingConventions
    

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39123 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Oliver Tappe
2010-10-24 12:57:55 +00:00
parent ed5692e03c
commit 6fd2f4a0d1
30 changed files with 1532 additions and 1732 deletions
+1
View File
@@ -13,6 +13,7 @@
#include <Format.h>
#include <FormatImpl.h>
#include <FormatParameters.h>
#include <FormattingConventions.h>
#include <GenericNumberFormat.h>
#include <IntegerFormat.h>
#include <IntegerFormatImpl.h>
+2 -14
View File
@@ -22,18 +22,9 @@ namespace icu_44 {
}
enum {
B_METRIC = 0,
B_US
};
class BCountry {
public:
BCountry(const char* languageCode,
const char* countryCode);
BCountry(const char* languageAndCountryCode
= "en_US");
BCountry(const char* countryCode = NULL);
BCountry(const BCountry& other);
BCountry& operator=(const BCountry& other);
~BCountry();
@@ -44,15 +35,12 @@ public:
) const;
const char* Code() const;
// ISO-3166
status_t GetIcon(BBitmap* result) const;
const char* GetLocalizedString(uint32 id) const;
status_t GetAvailableTimeZones(
BMessage* timeZones) const;
int8 Measurement() const;
class Private;
private:
friend class Private;
+129
View File
@@ -0,0 +1,129 @@
/*
* Copyright 2003-2010, Haiku, Inc.
* Distributed under the terms of the MIT Licence.
*/
#ifndef _FORMATTING_CONVENTIONS_H_
#define _FORMATTING_CONVENTIONS_H_
#include <Archivable.h>
#include <List.h>
#include <LocaleStrings.h>
#include <String.h>
#include <SupportDefs.h>
class BBitmap;
class BLanguage;
class BMessage;
namespace icu_44 {
class DateFormat;
class Locale;
}
enum BMeasurementKind {
B_METRIC = 0,
B_US
};
enum BDateFormatStyle {
B_FULL_DATE_FORMAT = 0,
B_LONG_DATE_FORMAT,
B_MEDIUM_DATE_FORMAT,
B_SHORT_DATE_FORMAT,
B_DATE_FORMAT_STYLE_COUNT
};
enum BTimeFormatStyle {
B_FULL_TIME_FORMAT = 0,
B_LONG_TIME_FORMAT,
B_MEDIUM_TIME_FORMAT,
B_SHORT_TIME_FORMAT,
B_TIME_FORMAT_STYLE_COUNT
};
class BFormattingConventions : public BArchivable {
public:
BFormattingConventions(const char* id = NULL);
BFormattingConventions(
const BFormattingConventions& other);
BFormattingConventions(const BMessage* archive);
BFormattingConventions& operator=(
const BFormattingConventions& other);
~BFormattingConventions();
bool operator==(
const BFormattingConventions& other) const;
bool operator!=(
const BFormattingConventions& other) const;
const char* ID() const;
const char* LanguageCode() const;
const char* CountryCode() const;
status_t GetNativeName(BString& name) const;
status_t GetName(BString& name,
const BLanguage* displayLanguage = NULL
) const;
const char* GetString(uint32 id) const;
status_t GetDateFormat(BDateFormatStyle style,
BString& outFormat) const;
status_t GetTimeFormat(BTimeFormatStyle style,
BString& outFormat) const;
status_t GetNumericFormat(BString& outFormat) const;
status_t GetMonetaryFormat(BString& outFormat) const;
void SetExplicitDateFormat(BDateFormatStyle style,
const BString& format);
void SetExplicitTimeFormat(BTimeFormatStyle style,
const BString& format);
void SetExplicitNumericFormat(const BString& format);
void SetExplicitMonetaryFormat(
const BString& format);
BMeasurementKind MeasurementKind() const;
bool UseStringsFromPreferredLanguage() const;
void SetUseStringsFromPreferredLanguage(bool value);
bool Use24HourClock() const;
void SetExplicitUse24HourClock(bool value);
void UnsetExplicitUse24HourClock();
virtual status_t Archive(BMessage* archive,
bool deep = true) const;
class Private;
private:
friend class Private;
mutable BString fCachedDateFormats[B_DATE_FORMAT_STYLE_COUNT];
mutable BString fCachedTimeFormats[B_TIME_FORMAT_STYLE_COUNT];
mutable BString fCachedNumericFormat;
mutable BString fCachedMonetaryFormat;
mutable int8 fCachedUse24HourClock;
BString fExplicitDateFormats[B_DATE_FORMAT_STYLE_COUNT];
BString fExplicitTimeFormats[B_TIME_FORMAT_STYLE_COUNT];
BString fExplicitNumericFormat;
BString fExplicitMonetaryFormat;
int8 fExplicitUse24HourClock;
bool fUseStringsFromPreferredLanguage;
icu_44::Locale* fICULocale;
};
#endif /* _FORMATTING_CONVENTIONS_H_ */
+45 -46
View File
@@ -7,11 +7,16 @@
#include <Collator.h>
#include <Country.h>
#include <FormattingConventions.h>
#include <Language.h>
#include <Locker.h>
namespace icu_44 {
class DateFormat;
}
class BCatalog;
class BString;
class BTimeZone;
@@ -39,7 +44,8 @@ typedef enum {
class BLocale {
public:
BLocale(const BLanguage* language = NULL,
const BCountry* country = NULL);
const BFormattingConventions* conventions
= NULL);
BLocale(const BLocale& other);
~BLocale();
@@ -47,14 +53,14 @@ public:
status_t GetCollator(BCollator* collator) const;
status_t GetLanguage(BLanguage* language) const;
status_t GetCountry(BCountry* country) const;
status_t GetFormattingConventions(
BFormattingConventions* conventions) const;
void SetCountry(const BCountry& newCountry);
void SetFormattingConventions(
const BFormattingConventions& conventions);
void SetCollator(const BCollator& newCollator);
void SetLanguage(const BLanguage& newLanguage);
bool GetName(BString& name) const;
// see definitions in LocaleStrings.h
const char* GetString(uint32 id) const;
@@ -62,29 +68,34 @@ public:
char* fmt, ...) const;
void FormatString(BString* buffer, char* fmt,
...) const;
status_t FormatDateTime(char* target, size_t maxSize,
time_t time, bool longFormat) const;
// DateTime
// TODO: drop some of these once BDateTimeFormat
// has been implemented!
ssize_t FormatDateTime(char* target, size_t maxSize,
time_t time, BDateFormatStyle dateStyle,
BTimeFormatStyle timeStyle) const;
status_t FormatDateTime(BString* buffer, time_t time,
bool longFormat,
BDateFormatStyle dateStyle,
BTimeFormatStyle timeStyle,
const BTimeZone* timeZone = NULL) const;
// Date
// TODO: drop some of these once BDateFormat
// has been implemented!
status_t FormatDate(char* string, size_t maxSize,
time_t time, bool longFormat) const;
ssize_t FormatDate(char* string, size_t maxSize,
time_t time, BDateFormatStyle style) const;
status_t FormatDate(BString* string, time_t time,
bool longFormat,
BDateFormatStyle style,
const BTimeZone* timeZone = NULL) const;
status_t FormatDate(BString* string,
int*& fieldPositions, int& fieldCount,
time_t time, bool longFormat) const;
time_t time, BDateFormatStyle style) const;
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& fieldCount, BDateFormatStyle style
) const;
int StartOfWeek() const;
@@ -92,29 +103,25 @@ public:
// TODO: drop some of these once BTimeFormat
// has been implemented!
status_t FormatTime(char* string, size_t maxSize,
time_t time, bool longFormat) const;
ssize_t FormatTime(char* string, size_t maxSize,
time_t time, BTimeFormatStyle style) const;
status_t FormatTime(BString* string, time_t time,
bool longFormat,
BTimeFormatStyle style,
const BTimeZone* timeZone = NULL) const;
status_t FormatTime(BString* string,
int*& fieldPositions, int& fieldCount,
time_t time, bool longFormat) const;
time_t time, BTimeFormatStyle style) const;
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;
int& fieldCount, BTimeFormatStyle style
) const;
// numbers
status_t FormatNumber(char* string, size_t maxSize,
ssize_t FormatNumber(char* string, size_t maxSize,
double value) const;
status_t FormatNumber(BString* string,
double value) const;
status_t FormatNumber(char* string, size_t maxSize,
ssize_t FormatNumber(char* string, size_t maxSize,
int32 value) const;
status_t FormatNumber(BString* string,
int32 value) const;
@@ -123,13 +130,8 @@ public:
ssize_t FormatMonetary(char* string, size_t maxSize,
double value) const;
ssize_t FormatMonetary(BString* string,
double value) const;
status_t FormatMonetary(BString* string,
int*& fieldPositions,
BNumberElement*& fieldTypes,
int& fieldCount, double value) const;
status_t GetCurrencySymbol(BString& result) const;
double value) const;
// Collator short-hands
int StringCompare(const char* s1,
@@ -138,21 +140,18 @@ public:
const BString* s2) const;
void GetSortKey(const char* string,
BString* key) const;
BString* sortKey) const;
private:
void _UpdateFormats();
icu_44::DateFormat* _CreateDateFormatter(
const BString& format) const;
icu_44::DateFormat* _CreateTimeFormatter(
const BString& format) const;
mutable BLocker fLock;
BCollator fCollator;
BCountry fCountry;
BFormattingConventions fConventions;
BLanguage fLanguage;
BString fLongDateFormat;
BString fShortDateFormat;
BString fLongTimeFormat;
BString fShortTimeFormat;
};
@@ -178,9 +177,9 @@ BLocale::StringCompare(const BString* s1, const BString* s2) const
inline void
BLocale::GetSortKey(const char* string, BString* key) const
BLocale::GetSortKey(const char* string, BString* sortKey) const
{
fCollator.GetSortKey(string, key);
fCollator.GetSortKey(string, sortKey);
}
+2 -2
View File
@@ -13,6 +13,7 @@ class BBitmap;
class BCatalog;
class BCollator;
class BCountry;
class BFormattingConventions;
class BLanguage;
class BLocale;
class BMessage;
@@ -37,7 +38,6 @@ public:
status_t GetPreferredLanguages(BMessage* message) const;
status_t GetAvailableLanguages(BMessage* message) const;
status_t GetAvailableCountries(
BMessage* timeZones) const;
status_t GetAvailableTimeZones(
@@ -49,7 +49,7 @@ public:
status_t GetFlagIconForCountry(BBitmap* flagIcon,
const char* countryCode);
status_t GetInstalledCatalogs(BMessage* message,
status_t GetAvailableCatalogs(BMessage* message,
const char* sigPattern = NULL,
const char* langPattern = NULL,
int32 fingerprint = 0) const;
-37
View File
@@ -1,37 +0,0 @@
/*
* Copyright 2010, Oliver Tappe <[email protected]>
* 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
@@ -0,0 +1,37 @@
/*
* Copyright 2010, Oliver Tappe <[email protected]>
* Distributed under the terms of the MIT License.
*/
#ifndef _FORMATTING_CONVENTIONS_PRIVATE_H
#define _FORMATTING_CONVENTIONS_PRIVATE_H
#include <FormattingConventions.h>
class BFormattingConventions::Private {
public:
Private(const BFormattingConventions* conventions = NULL)
:
fFormattingConventions(conventions)
{
}
void
SetTo(const BFormattingConventions* conventions)
{
fFormattingConventions = conventions;
}
icu_44::Locale*
ICULocale()
{
return fFormattingConventions->fICULocale;
}
private:
const BFormattingConventions* fFormattingConventions;
};
#endif // _FORMATTING_CONVENTIONS_PRIVATE_H
+8 -10
View File
@@ -7,7 +7,7 @@
#include <Collator.h>
#include <Country.h>
#include <FormattingConventions.h>
#include <image.h>
#include <Language.h>
#include <List.h>
@@ -34,10 +34,8 @@ public:
MutableLocaleRoster();
~MutableLocaleRoster();
status_t GetDefaultLocale(BLocale* locale) const;
status_t SetDefaultCountry(const BCountry& country);
status_t SetDefaultLocale(const BLocale& locale);
status_t SetDefaultFormattingConventions(
const BFormattingConventions& conventions);
status_t SetDefaultTimeZone(const BTimeZone& zone);
status_t SetPreferredLanguages(const BMessage* message);
@@ -127,8 +125,8 @@ struct RosterData {
static int CompareInfos(const void* left,
const void* right);
status_t SetDefaultCountry(const BCountry& country);
status_t SetDefaultLocale(const BLocale& locale);
status_t SetDefaultFormattingConventions(
const BFormattingConventions& convetions);
status_t SetDefaultTimeZone(const BTimeZone& zone);
status_t SetPreferredLanguages(const BMessage* msg);
private:
@@ -138,12 +136,12 @@ private:
status_t _LoadTimeSettings();
status_t _SaveTimeSettings();
status_t _SetDefaultCountry(const BCountry& country);
status_t _SetDefaultLocale(const BLocale& locale);
status_t _SetDefaultFormattingConventions(
const BFormattingConventions& conventions);
status_t _SetDefaultTimeZone(const BTimeZone& zone);
status_t _SetPreferredLanguages(const BMessage* msg);
status_t _AddDefaultCountryToMessage(
status_t _AddDefaultFormattingConventionsToMessage(
BMessage* message) const;
status_t _AddDefaultTimeZoneToMessage(
BMessage* message) const;
+5 -4
View File
@@ -38,7 +38,6 @@ All rights reserved.
#include <string.h>
#include <Catalog.h>
#include <Country.h>
#include <Debug.h>
#include <Locale.h>
#include <MenuItem.h>
@@ -251,7 +250,8 @@ TTimeView::ShowCalendar(BPoint where)
void
TTimeView::GetCurrentTime()
{
fLocale.FormatTime(fTimeStr, 64, fTime, fShowSeconds);
fLocale.FormatTime(fTimeStr, 64, fTime,
fShowSeconds ? B_MEDIUM_TIME_FORMAT : B_SHORT_TIME_FORMAT);
}
@@ -260,7 +260,7 @@ TTimeView::GetCurrentDate()
{
char tmp[64];
fLocale.FormatDate(tmp, 64, fTime, true);
fLocale.FormatDate(tmp, 64, fTime, B_FULL_DATE_FORMAT);
// 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)
@@ -297,7 +297,7 @@ TTimeView::MouseDown(BPoint point)
if (buttons == B_SECONDARY_MOUSE_BUTTON) {
ShowClockOptions(ConvertToScreen(point));
return;
} else if (buttons == B_PRIMARY_MOUSE_BUTTON)
} else if (buttons == B_PRIMARY_MOUSE_BUTTON)
ShowCalendar(point);
// invalidate last time/date strings and call the pulse
@@ -361,6 +361,7 @@ TTimeView::Update()
GetCurrentTime();
GetCurrentDate();
SetToolTip(fDateStr);
ResizeToPreferred();
@@ -15,6 +15,7 @@
#include <Font.h>
#include <FindDirectory.h>
#include <File.h>
#include <FormattingConventions.h>
#include <GroupLayoutBuilder.h>
#include <ListView.h>
#include <Locale.h>
@@ -212,8 +213,8 @@ BootPromptWindow::_InitCatalog(bool saveSettings)
gMutableLocaleRoster->SetPreferredLanguages(&settings);
BCountry country(language.String(), language.ToUpper());
gMutableLocaleRoster->SetDefaultCountry(country);
BFormattingConventions conventions(language.String());
gMutableLocaleRoster->SetDefaultFormattingConventions(conventions);
}
@@ -269,7 +270,7 @@ BootPromptWindow::_PopulateLanguages()
}
BMessage installedCatalogs;
be_locale_roster->GetInstalledCatalogs(&installedCatalogs,
be_locale_roster->GetAvailableCatalogs(&installedCatalogs,
"x-vnd.Haiku-ReadOnlyBootPrompt");
BFont font;
+1 -1
View File
@@ -83,7 +83,7 @@ TimedAlert::GetLabel(BString &string)
time(&t);
localtime_r(&t, &tm);
be_locale->FormatTime(timestring, 15, t, false);
be_locale->FormatTime(timestring, 15, t, B_SHORT_TIME_FORMAT);
string += " ";
string += timestring;
+4 -24
View File
@@ -30,16 +30,9 @@
#define ICU_VERSION icu_44
BCountry::BCountry(const char* languageCode, const char* countryCode)
BCountry::BCountry(const char* countryCode)
:
fICULocale(new ICU_VERSION::Locale(languageCode, countryCode))
{
}
BCountry::BCountry(const char* languageAndCountryCode)
:
fICULocale(new ICU_VERSION::Locale(languageAndCountryCode))
fICULocale(new ICU_VERSION::Locale("", countryCode))
{
}
@@ -98,6 +91,7 @@ BCountry::GetName(BString& name, const BLanguage* displayLanguage) const
UnicodeString uString;
fICULocale->getDisplayName(Locale(appLanguage), uString);
name.Truncate(0);
BStringByteSink stringConverter(&name);
uString.toUTF8(stringConverter);
@@ -108,7 +102,7 @@ BCountry::GetName(BString& name, const BLanguage* displayLanguage) const
const char*
BCountry::Code() const
{
return fICULocale->getName();
return fICULocale->getCountry();
}
@@ -128,17 +122,3 @@ BCountry::GetAvailableTimeZones(BMessage* timeZones) const
return be_locale_roster->GetAvailableTimeZonesForCountry(timeZones, Code());
}
// TODO does ICU even support this ? Is it in the keywords ?
int8
BCountry::Measurement() const
{
UErrorCode error = U_ZERO_ERROR;
switch (ulocdata_getMeasurementSystem(Code(), &error)) {
case UMS_US:
return B_US;
case UMS_SI:
default:
return B_METRIC;
}
}
+596
View File
@@ -0,0 +1,596 @@
/*
* Copyright 2003-2009, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2009-2010, Adrien Destugues, pulkomandy@gmail.com.
* Copyright 2010, Oliver Tappe <zooey@hirschkaefer.de>.
* Distributed under the terms of the MIT License.
*/
#include <FormattingConventions.h>
#include <AutoDeleter.h>
#include <IconUtils.h>
#include <List.h>
#include <Language.h>
#include <Locale.h>
#include <LocaleRoster.h>
#include <Resources.h>
#include <String.h>
#include <UnicodeChar.h>
#include <unicode/datefmt.h>
#include <unicode/locid.h>
#include <unicode/smpdtfmt.h>
#include <unicode/ulocdata.h>
#include <ICUWrapper.h>
#include <iostream>
#include <map>
#include <monetary.h>
#include <new>
#include <stdarg.h>
#include <stdlib.h>
#define ICU_VERSION icu_44
// #pragma mark - helpers
static bool
FormatUsesAmPm(const BString& format)
{
if (format.Length() == 0)
return false;
bool inQuote = false;
for (const char* s = format.String(); *s != '\0'; ++s) {
switch (*s) {
case '\'':
inQuote = !inQuote;
break;
case 'a':
if (!inQuote)
return true;
break;
}
}
return false;
}
static void
CoerceFormatTo12HourClock(BString& format)
{
char* s = format.LockBuffer(format.Length());
if (s == NULL)
return;
// change format to use h instead of H, k instead of K, and append an
// am/pm marker
bool inQuote = false;
for (; *s != '\0'; ++s) {
switch (*s) {
case '\'':
inQuote = !inQuote;
break;
case 'H':
if (!inQuote)
*s = 'h';
break;
case 'K':
if (!inQuote)
*s = 'k';
break;
}
}
format.UnlockBuffer(format.Length());
format.Append(" a");
}
static void
CoerceFormatTo24HourClock(BString& format)
{
char* buffer = format.LockBuffer(format.Length());
char* currentPos = buffer;
if (currentPos == NULL)
return;
// change the format to use H instead of h, K instead of k, and determine
// and remove the am/pm marker (including leading whitespace)
bool inQuote = false;
bool lastWasWhitespace = false;
uint32 ch;
const char* amPmStartPos = NULL;
const char* amPmEndPos = NULL;
const char* lastWhitespaceStart = NULL;
for (char* previousPos = currentPos; (ch = BUnicodeChar::FromUTF8(
(const char**)&currentPos)) != 0; previousPos = currentPos) {
switch (ch) {
case '\'':
inQuote = !inQuote;
break;
case 'h':
if (!inQuote)
*previousPos = 'H';
break;
case 'k':
if (!inQuote)
*previousPos = 'K';
break;
case 'a':
if (!inQuote) {
if (lastWasWhitespace)
amPmStartPos = lastWhitespaceStart;
else
amPmStartPos = previousPos;
amPmEndPos = currentPos;
}
break;
default:
if (!inQuote && BUnicodeChar::IsWhitespace(ch)) {
if (!lastWasWhitespace) {
lastWhitespaceStart = previousPos;
lastWasWhitespace = true;
}
continue;
}
}
lastWasWhitespace = false;
}
format.UnlockBuffer(format.Length());
if (amPmStartPos != NULL && amPmEndPos > amPmStartPos)
format.Remove(amPmStartPos - buffer, amPmEndPos - amPmStartPos);
}
static void
CoerceFormatToAbbreviatedTimezone(BString& format)
{
char* s = format.LockBuffer(format.Length());
if (s == NULL)
return;
// replace a single 'z' with 'V'
bool inQuote = false;
bool lastWasZ = false;
for (; *s != '\0'; ++s) {
switch (*s) {
case '\'':
inQuote = !inQuote;
break;
case 'z':
if (!inQuote && !lastWasZ && *(s+1) != 'z')
*s = 'V';
lastWasZ = true;
continue;
}
lastWasZ = false;
}
format.UnlockBuffer(format.Length());
}
// #pragma mark - BFormattingConventions
enum ClockHoursState {
CLOCK_HOURS_UNSET = 0,
CLOCK_HOURS_24,
CLOCK_HOURS_12
};
BFormattingConventions::BFormattingConventions(const char* id)
:
fCachedUse24HourClock(CLOCK_HOURS_UNSET),
fExplicitUse24HourClock(CLOCK_HOURS_UNSET),
fUseStringsFromPreferredLanguage(false),
fICULocale(new ICU_VERSION::Locale(id))
{
}
BFormattingConventions::BFormattingConventions(
const BFormattingConventions& other)
:
fCachedDateFormats(other.fCachedDateFormats),
fCachedTimeFormats(other.fCachedTimeFormats),
fCachedNumericFormat(other.fCachedNumericFormat),
fCachedMonetaryFormat(other.fCachedMonetaryFormat),
fCachedUse24HourClock(other.fCachedUse24HourClock),
fExplicitDateFormats(other.fExplicitDateFormats),
fExplicitTimeFormats(other.fExplicitTimeFormats),
fExplicitNumericFormat(other.fExplicitNumericFormat),
fExplicitMonetaryFormat(other.fExplicitMonetaryFormat),
fExplicitUse24HourClock(other.fExplicitUse24HourClock),
fUseStringsFromPreferredLanguage(other.fUseStringsFromPreferredLanguage),
fICULocale(new ICU_VERSION::Locale(*other.fICULocale))
{
}
BFormattingConventions::BFormattingConventions(const BMessage* archive)
{
BString conventionsID;
status_t status = archive->FindString("conventions", &conventionsID);
fICULocale = new ICU_VERSION::Locale(conventionsID);
for (int s = 0; s < B_DATE_FORMAT_STYLE_COUNT && status == B_OK; ++s) {
BString format;
status = archive->FindString("dateFormat", s, &format);
if (status == B_OK)
fExplicitDateFormats[s] = format;
status = archive->FindString("timeFormat", s, &format);
if (status == B_OK)
fExplicitTimeFormats[s] = format;
}
if (status == B_OK) {
int8 use24HourClock;
status = archive->FindInt8("use24HourClock", &use24HourClock);
if (status == B_OK)
fExplicitUse24HourClock = use24HourClock;
}
if (status == B_OK) {
bool useStringsFromPreferredLanguage;
status = archive->FindBool("useStringsFromPreferredLanguage",
&useStringsFromPreferredLanguage);
if (status == B_OK)
fUseStringsFromPreferredLanguage = useStringsFromPreferredLanguage;
}
}
BFormattingConventions&
BFormattingConventions::operator=(const BFormattingConventions& other)
{
if (this == &other)
return *this;
for (int s = 0; s < B_DATE_FORMAT_STYLE_COUNT; ++s)
fCachedDateFormats[s] = other.fCachedDateFormats[s];
for (int s = 0; s < B_TIME_FORMAT_STYLE_COUNT; ++s)
fCachedTimeFormats[s] = other.fCachedTimeFormats[s];
fCachedNumericFormat = other.fCachedNumericFormat;
fCachedMonetaryFormat = other.fCachedMonetaryFormat;
fCachedUse24HourClock = other.fCachedUse24HourClock;
for (int s = 0; s < B_DATE_FORMAT_STYLE_COUNT; ++s)
fExplicitDateFormats[s] = other.fExplicitDateFormats[s];
for (int s = 0; s < B_TIME_FORMAT_STYLE_COUNT; ++s)
fExplicitTimeFormats[s] = other.fExplicitTimeFormats[s];
fExplicitNumericFormat = other.fExplicitNumericFormat;
fExplicitMonetaryFormat = other.fExplicitMonetaryFormat;
fExplicitUse24HourClock = other.fExplicitUse24HourClock;
fUseStringsFromPreferredLanguage = other.fUseStringsFromPreferredLanguage;
*fICULocale = *other.fICULocale;
return *this;
}
BFormattingConventions::~BFormattingConventions()
{
delete fICULocale;
}
bool
BFormattingConventions::operator==(const BFormattingConventions& other) const
{
if (this == &other)
return true;
for (int s = 0; s < B_DATE_FORMAT_STYLE_COUNT; ++s) {
if (fExplicitDateFormats[s] != other.fExplicitDateFormats[s])
return false;
}
for (int s = 0; s < B_TIME_FORMAT_STYLE_COUNT; ++s) {
if (fExplicitTimeFormats[s] != other.fExplicitTimeFormats[s])
return false;
}
return fExplicitNumericFormat == other.fExplicitNumericFormat
&& fExplicitMonetaryFormat == other.fExplicitMonetaryFormat
&& fExplicitUse24HourClock == other.fExplicitUse24HourClock
&& fUseStringsFromPreferredLanguage
== other.fUseStringsFromPreferredLanguage
&& *fICULocale == *other.fICULocale;
}
bool
BFormattingConventions::operator!=(const BFormattingConventions& other) const
{
return !(*this == other);
}
const char*
BFormattingConventions::ID() const
{
return fICULocale->getName();
}
const char*
BFormattingConventions::LanguageCode() const
{
return fICULocale->getLanguage();
}
const char*
BFormattingConventions::CountryCode() const
{
const char* country = fICULocale->getCountry();
if (country == NULL || country[0] == '\0')
return NULL;
return country;
}
status_t
BFormattingConventions::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
BFormattingConventions::GetName(BString& name,
const BLanguage* displayLanguage) const
{
BString displayLanguageID;
if (displayLanguage == NULL) {
BLanguage defaultLanguage;
be_locale->GetLanguage(&defaultLanguage);
displayLanguageID = defaultLanguage.Code();
} else {
displayLanguageID = displayLanguage->Code();
}
UnicodeString uString;
fICULocale->getDisplayName(Locale(displayLanguageID.String()), uString);
name.Truncate(0);
BStringByteSink stringConverter(&name);
uString.toUTF8(stringConverter);
return B_OK;
}
BMeasurementKind
BFormattingConventions::MeasurementKind() const
{
UErrorCode error = U_ZERO_ERROR;
switch (ulocdata_getMeasurementSystem(ID(), &error)) {
case UMS_US:
return B_US;
case UMS_SI:
default:
return B_METRIC;
}
}
status_t
BFormattingConventions::GetDateFormat(BDateFormatStyle style,
BString& outFormat) const
{
if (style < 0 || style >= B_DATE_FORMAT_STYLE_COUNT)
return B_BAD_VALUE;
outFormat = fExplicitDateFormats[style].Length()
? fExplicitDateFormats[style]
: fCachedDateFormats[style];
if (outFormat.Length() > 0)
return B_OK;
ObjectDeleter<DateFormat> dateFormatter(
DateFormat::createDateInstance((DateFormat::EStyle)style, *fICULocale));
if (dateFormatter.Get() == NULL)
return B_NO_MEMORY;
SimpleDateFormat* dateFormatterImpl
= static_cast<SimpleDateFormat*>(dateFormatter.Get());
UnicodeString icuString;
dateFormatterImpl->toPattern(icuString);
BStringByteSink stringConverter(&outFormat);
icuString.toUTF8(stringConverter);
fCachedDateFormats[style] = outFormat;
return B_OK;
}
status_t
BFormattingConventions::GetTimeFormat(BTimeFormatStyle style,
BString& outFormat) const
{
if (style < 0 || style >= B_TIME_FORMAT_STYLE_COUNT)
return B_BAD_VALUE;
outFormat = fExplicitTimeFormats[style].Length()
? fExplicitTimeFormats[style]
: fCachedTimeFormats[style];
if (outFormat.Length() > 0)
return B_OK;
ObjectDeleter<DateFormat> timeFormatter(
DateFormat::createTimeInstance((DateFormat::EStyle)style, *fICULocale));
if (timeFormatter.Get() == NULL)
return B_NO_MEMORY;
SimpleDateFormat* timeFormatterImpl
= static_cast<SimpleDateFormat*>(timeFormatter.Get());
UnicodeString icuString;
timeFormatterImpl->toPattern(icuString);
BStringByteSink stringConverter(&outFormat);
icuString.toUTF8(stringConverter);
int8 use24HourClock = fExplicitUse24HourClock != CLOCK_HOURS_UNSET
? fExplicitUse24HourClock : fCachedUse24HourClock;
if (use24HourClock != CLOCK_HOURS_UNSET) {
// adjust to 12/24-hour clock as requested
bool localeUses24HourClock = !FormatUsesAmPm(outFormat);
if (localeUses24HourClock) {
if (use24HourClock == CLOCK_HOURS_12)
CoerceFormatTo12HourClock(outFormat);
} else {
if (use24HourClock == CLOCK_HOURS_24)
CoerceFormatTo24HourClock(outFormat);
}
}
// use abbreviated timezone in short timezone format
CoerceFormatToAbbreviatedTimezone(outFormat);
fCachedTimeFormats[style] = outFormat;
return B_OK;
}
status_t
BFormattingConventions::GetNumericFormat(BString& outFormat) const
{
// TODO!
return B_UNSUPPORTED;
}
status_t
BFormattingConventions::GetMonetaryFormat(BString& outFormat) const
{
// TODO!
return B_UNSUPPORTED;
}
void
BFormattingConventions::SetExplicitDateFormat(BDateFormatStyle style,
const BString& format)
{
fExplicitDateFormats[style] = format;
}
void
BFormattingConventions::SetExplicitTimeFormat(BTimeFormatStyle style,
const BString& format)
{
fExplicitTimeFormats[style] = format;
}
void
BFormattingConventions::SetExplicitNumericFormat(const BString& format)
{
fExplicitNumericFormat = format;
}
void
BFormattingConventions::SetExplicitMonetaryFormat(const BString& format)
{
fExplicitMonetaryFormat = format;
}
bool
BFormattingConventions::UseStringsFromPreferredLanguage() const
{
return fUseStringsFromPreferredLanguage;
}
void
BFormattingConventions::SetUseStringsFromPreferredLanguage(bool value)
{
fUseStringsFromPreferredLanguage = value;
}
bool
BFormattingConventions::Use24HourClock() const
{
int8 use24HourClock = fExplicitUse24HourClock != CLOCK_HOURS_UNSET
? fExplicitUse24HourClock : fCachedUse24HourClock;
if (use24HourClock == CLOCK_HOURS_UNSET) {
BString format;
GetTimeFormat(B_MEDIUM_TIME_FORMAT, format);
fCachedUse24HourClock
= FormatUsesAmPm(format) ? CLOCK_HOURS_12 : CLOCK_HOURS_24;
}
return fCachedUse24HourClock == CLOCK_HOURS_24;
}
void
BFormattingConventions::SetExplicitUse24HourClock(bool value)
{
int8 newUse24HourClock = value ? CLOCK_HOURS_24 : CLOCK_HOURS_12;
if (fExplicitUse24HourClock == newUse24HourClock)
return;
fExplicitUse24HourClock = newUse24HourClock;
for (int s = 0; s < B_TIME_FORMAT_STYLE_COUNT; ++s)
fCachedTimeFormats[s].Truncate(0);
}
void
BFormattingConventions::UnsetExplicitUse24HourClock()
{
fExplicitUse24HourClock = CLOCK_HOURS_UNSET;
for (int s = 0; s < B_TIME_FORMAT_STYLE_COUNT; ++s)
fCachedTimeFormats[s].Truncate(0);
}
status_t
BFormattingConventions::Archive(BMessage* archive, bool deep) const
{
status_t status = archive->AddString("conventions", fICULocale->getName());
for (int s = 0; s < B_DATE_FORMAT_STYLE_COUNT && status == B_OK; ++s) {
status = archive->AddString("dateFormat", fExplicitDateFormats[s]);
if (status == B_OK)
status = archive->AddString("timeFormat", fExplicitTimeFormats[s]);
}
if (status == B_OK)
status = archive->AddInt8("use24HourClock", fExplicitUse24HourClock);
if (status == B_OK) {
status = archive->AddBool("useStringsFromPreferredLanguage",
fUseStringsFromPreferredLanguage);
}
return status;
}
+1
View File
@@ -12,6 +12,7 @@ local sources =
Collator.cpp
Country.cpp
DefaultCatalog.cpp
FormattingConventions.cpp
HashMapCatalog.cpp
Language.cpp
LibbeLocaleBackend.cpp
+172 -442
View File
@@ -9,7 +9,7 @@
#include <Autolock.h>
#include <CalendarView.h>
#include <Catalog.h>
#include <CountryPrivate.h>
#include <FormattingConventionsPrivate.h>
#include <LanguagePrivate.h>
#include <Locale.h>
#include <LocaleRoster.h>
@@ -36,40 +36,25 @@ 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);
static void FetchDateFormat(bool longFormat, const Locale& locale,
BString& format);
static void FetchTimeFormat(bool longFormat, const Locale& locale,
BString& format);
BLocale::BLocale(const BLanguage* language, const BCountry* country)
BLocale::BLocale(const BLanguage* language,
const BFormattingConventions* conventions)
{
if (country != NULL)
fCountry = *country;
if (conventions != NULL)
fConventions = *conventions;
else
be_locale->GetCountry(&fCountry);
be_locale->GetFormattingConventions(&fConventions);
if (language != NULL)
fLanguage = *language;
else
be_locale->GetLanguage(&fLanguage);
_UpdateFormats();
}
BLocale::BLocale(const BLocale& other)
:
fCountry(other.fCountry),
fLanguage(other.fLanguage),
fLongDateFormat(other.fLongDateFormat),
fShortDateFormat(other.fShortDateFormat),
fLongTimeFormat(other.fLongTimeFormat),
fShortTimeFormat(other.fShortTimeFormat)
fConventions(other.fConventions),
fLanguage(other.fLanguage)
{
}
@@ -80,12 +65,12 @@ BLocale::operator=(const BLocale& other)
if (this == &other)
return *this;
fLongDateFormat = other.fLongDateFormat;
fShortDateFormat = other.fShortDateFormat;
fLongTimeFormat = other.fLongTimeFormat;
fShortTimeFormat = other.fShortTimeFormat;
BAutolock lock(fLock);
BAutolock otherLock(other.fLock);
if (!lock.IsLocked() || !otherLock.IsLocked())
return *this;
fCountry = other.fCountry;
fConventions = other.fConventions;
fLanguage = other.fLanguage;
return *this;
@@ -130,16 +115,16 @@ BLocale::GetLanguage(BLanguage* language) const
status_t
BLocale::GetCountry(BCountry* country) const
BLocale::GetFormattingConventions(BFormattingConventions* conventions) const
{
if (!country)
if (!conventions)
return B_BAD_VALUE;
BAutolock lock(fLock);
if (!lock.IsLocked())
return B_ERROR;
*country = fCountry;
*conventions = fConventions;
return B_OK;
}
@@ -165,15 +150,13 @@ BLocale::GetString(uint32 id) const
void
BLocale::SetCountry(const BCountry& newCountry)
BLocale::SetFormattingConventions(const BFormattingConventions& conventions)
{
BAutolock lock(fLock);
if (!lock.IsLocked())
return;
fCountry = newCountry;
_UpdateFormats();
fConventions = conventions;
}
@@ -199,80 +182,64 @@ BLocale::SetLanguage(const BLanguage& newLanguage)
}
bool
BLocale::GetName(BString& name) const
{
Locale icuLocale = Locale::createCanonical(fCountry.Code());
if (icuLocale.isBogus())
return false;
UnicodeString uString;
const Locale* countryLocale = BCountry::Private(&fCountry).ICULocale();
countryLocale->getDisplayName(icuLocale, uString);
BStringByteSink stringConverter(&name);
uString.toUTF8(stringConverter);
return true;
}
// #pragma mark - Date
status_t
ssize_t
BLocale::FormatDate(char* string, size_t maxSize, time_t time,
bool longFormat) const
BDateFormatStyle style) const
{
BAutolock lock(fLock);
if (!lock.IsLocked())
return B_ERROR;
ObjectDeleter<DateFormat> dateFormatter = CreateDateFormat(longFormat,
*BLanguage::Private(&fLanguage).ICULocale(),
longFormat ? fLongDateFormat : fShortDateFormat);
BString format;
fConventions.GetDateFormat(style, format);
ObjectDeleter<DateFormat> dateFormatter(_CreateDateFormatter(format));
if (dateFormatter.Get() == NULL)
return B_NO_MEMORY;
UnicodeString ICUString;
ICUString = dateFormatter->format((UDate)time * 1000, ICUString);
UnicodeString icuString;
dateFormatter->format((UDate)time * 1000, icuString);
CheckedArrayByteSink stringConverter(string, maxSize);
ICUString.toUTF8(stringConverter);
icuString.toUTF8(stringConverter);
if (stringConverter.Overflowed())
return B_BAD_VALUE;
return B_OK;
return stringConverter.NumberOfBytesWritten();
}
status_t
BLocale::FormatDate(BString *string, time_t time, bool longFormat,
BLocale::FormatDate(BString *string, time_t time, BDateFormatStyle style,
const BTimeZone* timeZone) const
{
BAutolock lock(fLock);
if (!lock.IsLocked())
return B_ERROR;
ObjectDeleter<DateFormat> dateFormatter = CreateDateFormat(longFormat,
*BLanguage::Private(&fLanguage).ICULocale(),
longFormat ? fLongDateFormat : fShortDateFormat);
BString format;
fConventions.GetDateFormat(style, format);
ObjectDeleter<DateFormat> dateFormatter(_CreateDateFormatter(format));
if (dateFormatter.Get() == NULL)
return B_NO_MEMORY;
if (timeZone != NULL) {
ObjectDeleter<TimeZone> icuTimeZone
= TimeZone::createTimeZone(timeZone->ID().String());
ObjectDeleter<TimeZone> icuTimeZone(
TimeZone::createTimeZone(timeZone->ID().String()));
if (icuTimeZone.Get() == NULL)
return B_NO_MEMORY;
dateFormatter->setTimeZone(*icuTimeZone.Get());
}
UnicodeString ICUString;
ICUString = dateFormatter->format((UDate)time * 1000, ICUString);
UnicodeString icuString;
dateFormatter->format((UDate)time * 1000, icuString);
string->Truncate(0);
BStringByteSink stringConverter(string);
ICUString.toUTF8(stringConverter);
icuString.toUTF8(stringConverter);
return B_OK;
}
@@ -280,24 +247,24 @@ BLocale::FormatDate(BString *string, time_t time, bool longFormat,
status_t
BLocale::FormatDate(BString* string, int*& fieldPositions, int& fieldCount,
time_t time, bool longFormat) const
time_t time, BDateFormatStyle style) const
{
BAutolock lock(fLock);
if (!lock.IsLocked())
return B_ERROR;
ObjectDeleter<DateFormat> dateFormatter = CreateDateFormat(longFormat,
*BLanguage::Private(&fLanguage).ICULocale(),
longFormat ? fLongDateFormat : fShortDateFormat);
BString format;
fConventions.GetDateFormat(style, format);
ObjectDeleter<DateFormat> dateFormatter(_CreateDateFormatter(format));
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);
UnicodeString icuString;
dateFormatter->format((UDate)time * 1000, icuString, &positionIterator,
error);
if (error != U_ZERO_ERROR)
return B_ERROR;
@@ -319,57 +286,7 @@ BLocale::FormatDate(BString* string, int*& fieldPositions, int& fieldCount,
string->Truncate(0);
BStringByteSink stringConverter(string);
ICUString.toUTF8(stringConverter);
return B_OK;
}
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)
format = fShortDateFormat;
else {
format.Truncate(0);
ObjectDeleter<DateFormat> dateFormatter = CreateDateFormat(longFormat,
*BCountry::Private(&fCountry).ICULocale(), format);
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)
{
BAutolock lock(fLock);
if (!lock.IsLocked())
return B_ERROR;
if (longFormat)
fLongDateFormat = formatString;
else
fShortDateFormat = formatString;
icuString.toUTF8(stringConverter);
return B_OK;
}
@@ -377,24 +294,24 @@ BLocale::SetDateFormat(const char* formatString, bool longFormat)
status_t
BLocale::GetDateFields(BDateElement*& fields, int& fieldCount,
bool longFormat) const
BDateFormatStyle style) const
{
BAutolock lock(fLock);
if (!lock.IsLocked())
return B_ERROR;
ObjectDeleter<DateFormat> dateFormatter = CreateDateFormat(longFormat,
*BCountry::Private(&fCountry).ICULocale(),
longFormat ? fLongDateFormat : fShortDateFormat);
BString format;
fConventions.GetDateFormat(style, format);
ObjectDeleter<DateFormat> dateFormatter(_CreateDateFormatter(format));
if (dateFormatter.Get() == NULL)
return B_NO_MEMORY;
fields = NULL;
UErrorCode error = U_ZERO_ERROR;
ICU_VERSION::FieldPositionIterator positionIterator;
UnicodeString ICUString;
UnicodeString icuString;
time_t now;
ICUString = dateFormatter->format((UDate)time(&now) * 1000, ICUString,
dateFormatter->format((UDate)time(&now) * 1000, icuString,
&positionIterator, error);
if (U_FAILURE(error))
@@ -439,9 +356,9 @@ BLocale::StartOfWeek() const
return B_ERROR;
UErrorCode err = U_ZERO_ERROR;
Calendar* c
= Calendar::createInstance(*BCountry::Private(&fCountry).ICULocale(),
err);
Calendar* c = Calendar::createInstance(
*BFormattingConventions::Private(&fConventions).ICULocale(),
err);
if (err == U_ZERO_ERROR && c->getFirstDayOfWeek(err) == UCAL_SUNDAY) {
delete c;
@@ -454,81 +371,78 @@ BLocale::StartOfWeek() const
}
status_t
ssize_t
BLocale::FormatDateTime(char* target, size_t maxSize, time_t time,
bool longFormat) const
BDateFormatStyle dateStyle, BTimeFormatStyle timeStyle) const
{
BAutolock lock(fLock);
if (!lock.IsLocked())
return B_ERROR;
ObjectDeleter<DateFormat> dateFormatter = CreateDateFormat(longFormat,
*BLanguage::Private(&fLanguage).ICULocale(),
longFormat ? fLongDateFormat : fShortDateFormat);
BString format;
fConventions.GetDateFormat(dateStyle, format);
ObjectDeleter<DateFormat> dateFormatter(_CreateDateFormatter(format));
if (dateFormatter.Get() == NULL)
return B_NO_MEMORY;
ObjectDeleter<DateFormat> timeFormatter = CreateTimeFormat(longFormat,
*BLanguage::Private(&fLanguage).ICULocale(),
longFormat ? fLongTimeFormat : fShortTimeFormat);
fConventions.GetTimeFormat(timeStyle, format);
ObjectDeleter<DateFormat> timeFormatter(_CreateTimeFormatter(format));
if (timeFormatter.Get() == NULL)
return B_NO_MEMORY;
UnicodeString ICUString;
ICUString = dateFormatter->format((UDate)time * 1000, ICUString);
UnicodeString icuString;
dateFormatter->format((UDate)time * 1000, icuString);
ICUString.append(UnicodeString::fromUTF8(", "));
icuString.append(UnicodeString::fromUTF8(", "));
ICUString = timeFormatter->format((UDate)time * 1000, ICUString);
timeFormatter->format((UDate)time * 1000, icuString);
CheckedArrayByteSink stringConverter(target, maxSize);
ICUString.toUTF8(stringConverter);
icuString.toUTF8(stringConverter);
if (stringConverter.Overflowed())
return B_BAD_VALUE;
return B_OK;
return stringConverter.NumberOfBytesWritten();
}
status_t
BLocale::FormatDateTime(BString* target, time_t time, bool longFormat,
BLocale::FormatDateTime(BString* target, time_t time,
BDateFormatStyle dateStyle, BTimeFormatStyle timeStyle,
const BTimeZone* timeZone) const
{
BAutolock lock(fLock);
if (!lock.IsLocked())
return B_ERROR;
ObjectDeleter<DateFormat> dateFormatter = CreateDateFormat(longFormat,
*BLanguage::Private(&fLanguage).ICULocale(),
longFormat ? fLongDateFormat : fShortDateFormat);
BString format;
fConventions.GetDateFormat(dateStyle, format);
ObjectDeleter<DateFormat> dateFormatter(_CreateDateFormatter(format));
if (dateFormatter.Get() == NULL)
return B_NO_MEMORY;
ObjectDeleter<DateFormat> timeFormatter = CreateTimeFormat(longFormat,
*BLanguage::Private(&fLanguage).ICULocale(),
longFormat ? fLongTimeFormat : fShortTimeFormat);
fConventions.GetTimeFormat(timeStyle, format);
ObjectDeleter<DateFormat> timeFormatter(_CreateTimeFormatter(format));
if (timeFormatter.Get() == NULL)
return B_NO_MEMORY;
if (timeZone != NULL) {
ObjectDeleter<TimeZone> icuTimeZone
= TimeZone::createTimeZone(timeZone->ID().String());
ObjectDeleter<TimeZone> icuTimeZone(
TimeZone::createTimeZone(timeZone->ID().String()));
if (icuTimeZone.Get() == NULL)
return B_NO_MEMORY;
timeFormatter->setTimeZone(*icuTimeZone.Get());
}
UnicodeString ICUString;
ICUString = dateFormatter->format((UDate)time * 1000, ICUString);
ICUString.append(UnicodeString::fromUTF8(", "));
ICUString = timeFormatter->format((UDate)time * 1000, ICUString);
UnicodeString icuString;
dateFormatter->format((UDate)time * 1000, icuString);
icuString.append(UnicodeString::fromUTF8(", "));
timeFormatter->format((UDate)time * 1000, icuString);
target->Truncate(0);
BStringByteSink stringConverter(target);
ICUString.toUTF8(stringConverter);
icuString.toUTF8(stringConverter);
return B_OK;
}
@@ -537,63 +451,61 @@ BLocale::FormatDateTime(BString* target, time_t time, bool longFormat,
// #pragma mark - Time
status_t
ssize_t
BLocale::FormatTime(char* string, size_t maxSize, time_t time,
bool longFormat) const
BTimeFormatStyle style) const
{
BAutolock lock(fLock);
if (!lock.IsLocked())
return B_ERROR;
ObjectDeleter<DateFormat> timeFormatter = CreateTimeFormat(longFormat,
*BLanguage::Private(&fLanguage).ICULocale(),
longFormat ? fLongTimeFormat : fShortTimeFormat);
BString format;
fConventions.GetTimeFormat(style, format);
ObjectDeleter<DateFormat> timeFormatter(_CreateTimeFormatter(format));
if (timeFormatter.Get() == NULL)
return B_NO_MEMORY;
UnicodeString ICUString;
ICUString = timeFormatter->format((UDate)time * 1000, ICUString);
UnicodeString icuString;
timeFormatter->format((UDate)time * 1000, icuString);
CheckedArrayByteSink stringConverter(string, maxSize);
ICUString.toUTF8(stringConverter);
icuString.toUTF8(stringConverter);
if (stringConverter.Overflowed())
return B_BAD_VALUE;
return B_OK;
return stringConverter.NumberOfBytesWritten();
}
status_t
BLocale::FormatTime(BString* string, time_t time, bool longFormat,
BLocale::FormatTime(BString* string, time_t time, BTimeFormatStyle style,
const BTimeZone* timeZone) const
{
BAutolock lock(fLock);
if (!lock.IsLocked())
return B_ERROR;
ObjectDeleter<DateFormat> timeFormatter = CreateTimeFormat(longFormat,
*BLanguage::Private(&fLanguage).ICULocale(),
longFormat ? fLongTimeFormat : fShortTimeFormat);
BString format;
fConventions.GetTimeFormat(style, format);
ObjectDeleter<DateFormat> timeFormatter(_CreateTimeFormatter(format));
if (timeFormatter.Get() == NULL)
return B_NO_MEMORY;
if (timeZone != NULL) {
ObjectDeleter<TimeZone> icuTimeZone
= TimeZone::createTimeZone(timeZone->ID().String());
ObjectDeleter<TimeZone> icuTimeZone(
TimeZone::createTimeZone(timeZone->ID().String()));
if (icuTimeZone.Get() == NULL)
return B_NO_MEMORY;
timeFormatter->setTimeZone(*icuTimeZone.Get());
}
UnicodeString ICUString;
ICUString = timeFormatter->format((UDate)time * 1000, ICUString);
UnicodeString icuString;
timeFormatter->format((UDate)time * 1000, icuString);
string->Truncate(0);
BStringByteSink stringConverter(string);
ICUString.toUTF8(stringConverter);
icuString.toUTF8(stringConverter);
return B_OK;
}
@@ -601,24 +513,24 @@ BLocale::FormatTime(BString* string, time_t time, bool longFormat,
status_t
BLocale::FormatTime(BString* string, int*& fieldPositions, int& fieldCount,
time_t time, bool longFormat) const
time_t time, BTimeFormatStyle style) const
{
BAutolock lock(fLock);
if (!lock.IsLocked())
return B_ERROR;
ObjectDeleter<DateFormat> timeFormatter = CreateTimeFormat(longFormat,
*BLanguage::Private(&fLanguage).ICULocale(),
longFormat ? fLongTimeFormat : fShortTimeFormat);
BString format;
fConventions.GetTimeFormat(style, format);
ObjectDeleter<DateFormat> timeFormatter(_CreateTimeFormatter(format));
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);
UnicodeString icuString;
timeFormatter->format((UDate)time * 1000, icuString, &positionIterator,
error);
if (error != U_ZERO_ERROR)
return B_ERROR;
@@ -639,8 +551,7 @@ BLocale::FormatTime(BString* string, int*& fieldPositions, int& fieldCount,
string->Truncate(0);
BStringByteSink stringConverter(string);
ICUString.toUTF8(stringConverter);
icuString.toUTF8(stringConverter);
return B_OK;
}
@@ -648,24 +559,24 @@ BLocale::FormatTime(BString* string, int*& fieldPositions, int& fieldCount,
status_t
BLocale::GetTimeFields(BDateElement*& fields, int& fieldCount,
bool longFormat) const
BTimeFormatStyle style) const
{
BAutolock lock(fLock);
if (!lock.IsLocked())
return B_ERROR;
ObjectDeleter<DateFormat> timeFormatter = CreateTimeFormat(longFormat,
*BCountry::Private(&fCountry).ICULocale(),
longFormat ? fLongTimeFormat : fShortTimeFormat);
BString format;
fConventions.GetTimeFormat(style, format);
ObjectDeleter<DateFormat> timeFormatter(_CreateTimeFormatter(format));
if (timeFormatter.Get() == NULL)
return B_NO_MEMORY;
fields = NULL;
UErrorCode error = U_ZERO_ERROR;
ICU_VERSION::FieldPositionIterator positionIterator;
UnicodeString ICUString;
UnicodeString icuString;
time_t now;
ICUString = timeFormatter->format((UDate)time(&now) * 1000, ICUString,
timeFormatter->format((UDate)time(&now) * 1000, icuString,
&positionIterator, error);
if (error != U_ZERO_ERROR)
@@ -708,82 +619,18 @@ 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
fShortTimeFormat = formatString;
return B_OK;
}
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)
format = fShortTimeFormat;
else {
format.Truncate(0);
ObjectDeleter<DateFormat> timeFormatter = CreateTimeFormat(longFormat,
*BCountry::Private(&fCountry).ICULocale(),
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;
}
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
status_t
ssize_t
BLocale::FormatNumber(char* string, size_t maxSize, double value) const
{
BString fullString;
status_t status = FormatNumber(&fullString, value);
if (status == B_OK)
strlcpy(string, fullString.String(), maxSize);
if (status != B_OK)
return status;
return status;
return strlcpy(string, fullString.String(), maxSize);
}
@@ -795,35 +642,35 @@ BLocale::FormatNumber(BString* string, double value) const
return B_ERROR;
UErrorCode err = U_ZERO_ERROR;
ObjectDeleter<NumberFormat> numberFormatter = NumberFormat::createInstance(
*BCountry::Private(&fCountry).ICULocale(), NumberFormat::kNumberStyle,
err);
ObjectDeleter<NumberFormat> numberFormatter(NumberFormat::createInstance(
*BFormattingConventions::Private(&fConventions).ICULocale(),
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);
UnicodeString icuString;
numberFormatter->format(value, icuString);
string->Truncate(0);
BStringByteSink stringConverter(string);
ICUString.toUTF8(stringConverter);
icuString.toUTF8(stringConverter);
return B_OK;
}
status_t
ssize_t
BLocale::FormatNumber(char* string, size_t maxSize, int32 value) const
{
BString fullString;
status_t status = FormatNumber(&fullString, value);
if (status == B_OK)
strlcpy(string, fullString.String(), maxSize);
if (status != B_OK)
return status;
return status;
return strlcpy(string, fullString.String(), maxSize);
}
@@ -835,21 +682,21 @@ BLocale::FormatNumber(BString* string, int32 value) const
return B_ERROR;
UErrorCode err = U_ZERO_ERROR;
ObjectDeleter<NumberFormat> numberFormatter = NumberFormat::createInstance(
*BCountry::Private(&fCountry).ICULocale(), NumberFormat::kNumberStyle,
err);
ObjectDeleter<NumberFormat> numberFormatter(NumberFormat::createInstance(
*BFormattingConventions::Private(&fConventions).ICULocale(),
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);
UnicodeString icuString;
numberFormatter->format((int32_t)value, icuString);
string->Truncate(0);
BStringByteSink stringConverter(string);
ICUString.toUTF8(stringConverter);
icuString.toUTF8(stringConverter);
return B_OK;
}
@@ -859,15 +706,15 @@ ssize_t
BLocale::FormatMonetary(char* string, size_t maxSize, double value) const
{
BString fullString;
ssize_t written = FormatMonetary(&fullString, value);
if (written < 0)
return written;
status_t status = FormatMonetary(&fullString, value);
if (status != B_OK)
return status;
return strlcpy(string, fullString.String(), maxSize);
}
ssize_t
status_t
BLocale::FormatMonetary(BString* string, double value) const
{
if (string == NULL)
@@ -877,186 +724,69 @@ BLocale::FormatMonetary(BString* string, double value) const
if (!lock.IsLocked())
return B_ERROR;
UErrorCode err;
ObjectDeleter<NumberFormat> numberFormatter
= NumberFormat::createCurrencyInstance(
*BCountry::Private(&fCountry).ICULocale(), err);
UErrorCode err = U_ZERO_ERROR;
ObjectDeleter<NumberFormat> numberFormatter(
NumberFormat::createCurrencyInstance(
*BFormattingConventions::Private(&fConventions).ICULocale(),
err));
if (numberFormatter.Get() == NULL)
return B_NO_MEMORY;
if (U_FAILURE(err))
return B_ERROR;
UnicodeString ICUString;
ICUString = numberFormatter->format(value, ICUString);
UnicodeString icuString;
numberFormatter->format(value, icuString);
string->Truncate(0);
BStringByteSink stringConverter(string);
ICUString.toUTF8(stringConverter);
return string->Length();
}
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(
*BCountry::Private(&fCountry).ICULocale(), err);
if (U_FAILURE(err))
return B_NO_MEMORY;
fieldPositions = NULL;
fieldTypes = NULL;
ICU_VERSION::FieldPositionIterator positionIterator;
UnicodeString ICUString;
ICUString = numberFormatter->format(value, ICUString, &positionIterator,
err);
if (err != U_ZERO_ERROR)
return B_ERROR;
ICU_VERSION::FieldPosition field;
std::vector<int> fieldPosStorage;
std::vector<int> fieldTypeStorage;
fieldCount = 0;
while (positionIterator.next(field)) {
fieldTypeStorage.push_back(field.getField());
fieldPosStorage.push_back(field.getBeginIndex() | (field.getEndIndex() << 16));
fieldCount ++;
}
fieldPositions = (int*) malloc(fieldCount * sizeof(int));
fieldTypes = (BNumberElement*) malloc(fieldCount * sizeof(BNumberElement));
for (int i = 0 ; i < fieldCount ; i++ ) {
fieldPositions[i] = fieldPosStorage[i];
switch (fieldTypeStorage[i]) {
case NumberFormat::kCurrencyField:
fieldTypes[i] = B_NUMBER_ELEMENT_CURRENCY;
break;
case NumberFormat::kIntegerField:
fieldTypes[i] = B_NUMBER_ELEMENT_INTEGER;
break;
case NumberFormat::kFractionField:
fieldTypes[i] = B_NUMBER_ELEMENT_FRACTIONAL;
break;
default:
fieldTypes[i] = B_NUMBER_ELEMENT_INVALID;
break;
}
}
string->Truncate(0);
BStringByteSink stringConverter(string);
ICUString.toUTF8(stringConverter);
icuString.toUTF8(stringConverter);
return B_OK;
}
status_t
BLocale::GetCurrencySymbol(BString& result) const
DateFormat*
BLocale::_CreateDateFormatter(const BString& format) const
{
BAutolock lock(fLock);
if (!lock.IsLocked())
return B_ERROR;
Locale* icuLocale
= fConventions.UseStringsFromPreferredLanguage()
? BLanguage::Private(&fLanguage).ICULocale()
: BFormattingConventions::Private(&fConventions).ICULocale();
UErrorCode error = U_ZERO_ERROR;
NumberFormat* format = NumberFormat::createCurrencyInstance(
*BCountry::Private(&fCountry).ICULocale(), error);
DateFormat* dateFormatter
= DateFormat::createDateInstance(DateFormat::kShort, *icuLocale);
if (dateFormatter == NULL)
return NULL;
if (U_FAILURE(error))
return B_ERROR;
SimpleDateFormat* dateFormatterImpl
= static_cast<SimpleDateFormat*>(dateFormatter);
char* symbol = (char*)malloc(20);
u_strToUTF8(symbol, 20, NULL, format->getCurrency(), -1, &error);
if (U_FAILURE(error))
return B_BAD_DATA;
result.Append(symbol);
delete format;
delete symbol;
return B_OK;
}
// #pragma mark - Helpers
static DateFormat*
CreateDateFormat(bool longFormat, const Locale& locale, const BString& format)
{
DateFormat* dateFormatter = DateFormat::createDateInstance(
longFormat ? DateFormat::kFull : DateFormat::kShort, locale);
if (format.Length() > 0) {
SimpleDateFormat* dateFormatterImpl
= static_cast<SimpleDateFormat*>(dateFormatter);
UnicodeString pattern(format.String());
dateFormatterImpl->applyPattern(pattern);
}
UnicodeString pattern(format.String());
dateFormatterImpl->applyPattern(pattern);
return dateFormatter;
}
static DateFormat*
CreateTimeFormat(bool longFormat, const Locale& locale, const BString& format)
DateFormat*
BLocale::_CreateTimeFormatter(const BString& format) const
{
DateFormat* timeFormatter = DateFormat::createTimeInstance(
longFormat ? DateFormat::kMedium: DateFormat::kShort, locale);
Locale* icuLocale
= fConventions.UseStringsFromPreferredLanguage()
? BLanguage::Private(&fLanguage).ICULocale()
: BFormattingConventions::Private(&fConventions).ICULocale();
if (format.Length() > 0) {
SimpleDateFormat* timeFormatterImpl
= static_cast<SimpleDateFormat*>(timeFormatter);
UnicodeString pattern(format.String());
timeFormatterImpl->applyPattern(pattern);
}
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);
DateFormat* timeFormatter
= DateFormat::createTimeInstance(DateFormat::kShort, *icuLocale);
if (timeFormatter == NULL)
return NULL;
SimpleDateFormat* timeFormatterImpl
= static_cast<SimpleDateFormat*>(timeFormatter);
UnicodeString pattern;
timeFormatterImpl->toPattern(pattern);
format.Truncate(0);
BStringByteSink stringConverter(&format);
pattern.toUTF8(stringConverter);
UnicodeString pattern(format.String());
timeFormatterImpl->applyPattern(pattern);
return timeFormatter;
}
+3 -3
View File
@@ -20,11 +20,11 @@
#include <Bitmap.h>
#include <Catalog.h>
#include <Collator.h>
#include <Country.h>
#include <DefaultCatalog.h>
#include <Directory.h>
#include <Entry.h>
#include <File.h>
#include <FormattingConventions.h>
#include <IconUtils.h>
#include <Language.h>
#include <Locale.h>
@@ -261,8 +261,8 @@ BLocaleRoster::GetFlagIconForCountry(BBitmap* flagIcon, const char* countryCode)
status_t
BLocaleRoster::GetInstalledCatalogs(BMessage* languageList,
const char* sigPattern, const char* langPattern, int32 fingerprint) const
BLocaleRoster::GetAvailableCatalogs(BMessage* languageList,
const char* sigPattern, const char* langPattern, int32 fingerprint) const
{
if (languageList == NULL)
return B_BAD_VALUE;
+40 -121
View File
@@ -18,12 +18,12 @@
#include <Autolock.h>
#include <Catalog.h>
#include <Collator.h>
#include <Country.h>
#include <DefaultCatalog.h>
#include <Directory.h>
#include <Entry.h>
#include <File.h>
#include <FindDirectory.h>
#include <FormattingConventions.h>
#include <Language.h>
#include <Locale.h>
#include <Node.h>
@@ -129,6 +129,11 @@ RosterData gRosterData;
static const char* kPriorityAttr = "ADDON:priority";
static const char* kLanguageField = "language";
static const char* kTimezoneField = "timezone";
static const char* kOffsetField = "offset";
RosterData::RosterData()
:
@@ -322,7 +327,8 @@ RosterData::CleanupCatalogAddOns()
status_t
RosterData::SetDefaultCountry(const BCountry& newCountry)
RosterData::SetDefaultFormattingConventions(
const BFormattingConventions& newFormattingConventions)
{
status_t status = B_OK;
@@ -330,40 +336,14 @@ RosterData::SetDefaultCountry(const BCountry& newCountry)
if (!lock.IsLocked())
return B_ERROR;
status = _SetDefaultCountry(newCountry);
status = _SetDefaultFormattingConventions(newFormattingConventions);
if (status == B_OK)
status = _SaveLocaleSettings();
if (status == B_OK) {
BMessage updateMessage(B_LOCALE_CHANGED);
status = _AddDefaultCountryToMessage(&updateMessage);
if (status == B_OK)
status = be_roster->Broadcast(&updateMessage);
}
return status;
}
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
status = _AddDefaultFormattingConventionsToMessage(&updateMessage);
if (status == B_OK)
status = be_roster->Broadcast(&updateMessage);
}
@@ -437,21 +417,8 @@ RosterData::_LoadLocaleSettings()
status = settings.Unflatten(&file);
if (status == B_OK) {
BString codeName;
BLocale newDefaultLocale;
if (settings.FindString("country", &codeName) == B_OK) {
BCountry country(codeName);
newDefaultLocale = BLocale(NULL, &country);
}
BString timeFormat;
if (settings.FindString("shortTimeFormat", &timeFormat) == B_OK)
newDefaultLocale.SetTimeFormat(timeFormat, false);
if (settings.FindString("longTimeFormat", &timeFormat) == B_OK)
newDefaultLocale.SetTimeFormat(timeFormat, true);
_SetDefaultLocale(newDefaultLocale);
BFormattingConventions conventions(&settings);
fDefaultLocale.SetFormattingConventions(conventions);
_SetPreferredLanguages(&settings);
@@ -463,9 +430,11 @@ RosterData::_LoadLocaleSettings()
// set everything to default values
fPreferredLanguages.MakeEmpty();
fPreferredLanguages.AddString("language", "en");
fPreferredLanguages.AddString(kLanguageField, "en");
BLanguage defaultLanguage("en_US");
_SetDefaultLocale(BLocale(&defaultLanguage));
fDefaultLocale.SetLanguage(defaultLanguage);
BFormattingConventions conventions("en_US");
fDefaultLocale.SetFormattingConventions(conventions);
return status;
}
@@ -486,7 +455,7 @@ RosterData::_LoadTimeSettings()
status = settings.Unflatten(&file);
if (status == B_OK) {
BString timeZoneID;
if (settings.FindString("timezone", &timeZoneID) == B_OK)
if (settings.FindString(kTimezoneField, &timeZoneID) == B_OK)
_SetDefaultTimeZone(BTimeZone(timeZoneID.String()));
else
_SetDefaultTimeZone(BTimeZone(BTimeZone::kNameOfGmtZone));
@@ -506,7 +475,7 @@ status_t
RosterData::_SaveLocaleSettings()
{
BMessage settings;
status_t status = _AddDefaultCountryToMessage(&settings);
status_t status = _AddDefaultFormattingConventionsToMessage(&settings);
if (status == B_OK)
_AddPreferredLanguagesToMessage(&settings);
@@ -555,32 +524,13 @@ RosterData::_SaveTimeSettings()
status_t
RosterData::_SetDefaultCountry(const BCountry& newCountry)
RosterData::_SetDefaultFormattingConventions(
const BFormattingConventions& newFormattingConventions)
{
fDefaultLocale.SetCountry(newCountry);
fDefaultLocale.SetFormattingConventions(newFormattingConventions);
UErrorCode icuError = U_ZERO_ERROR;
Locale icuLocale = Locale::createCanonical(newCountry.Code());
if (icuLocale.isBogus())
return B_ERROR;
Locale::setDefault(icuLocale, icuError);
if (!U_SUCCESS(icuError))
return B_ERROR;
return B_OK;
}
status_t
RosterData::_SetDefaultLocale(const BLocale& newLocale)
{
fDefaultLocale = newLocale;
UErrorCode icuError = U_ZERO_ERROR;
BCountry defaultCountry;
newLocale.GetCountry(&defaultCountry);
Locale icuLocale = Locale::createCanonical(defaultCountry.Code());
Locale icuLocale = Locale::createCanonical(newFormattingConventions.ID());
if (icuLocale.isBogus())
return B_ERROR;
@@ -611,18 +561,18 @@ RosterData::_SetPreferredLanguages(const BMessage* languages)
{
BString langName;
if (languages != NULL
&& languages->FindString("language", &langName) == B_OK) {
&& languages->FindString(kLanguageField, &langName) == B_OK) {
fDefaultLocale.SetCollator(BCollator(langName.String()));
fDefaultLocale.SetLanguage(BLanguage(langName.String()));
fPreferredLanguages.RemoveName("language");
for (int i = 0; languages->FindString("language", i, &langName) == B_OK;
i++) {
fPreferredLanguages.AddString("language", langName);
fPreferredLanguages.RemoveName(kLanguageField);
for (int i = 0; languages->FindString(kLanguageField, i, &langName)
== B_OK; i++) {
fPreferredLanguages.AddString(kLanguageField, langName);
}
} else {
fPreferredLanguages.MakeEmpty();
fPreferredLanguages.AddString("language", "en");
fPreferredLanguages.AddString(kLanguageField, "en");
fDefaultLocale.SetCollator(BCollator("en"));
}
@@ -631,34 +581,26 @@ RosterData::_SetPreferredLanguages(const BMessage* languages)
status_t
RosterData::_AddDefaultCountryToMessage(BMessage* message) const
RosterData::_AddDefaultFormattingConventionsToMessage(BMessage* message) const
{
BCountry defaultCountry;
fDefaultLocale.GetCountry(&defaultCountry);
status_t status = message->AddString("country", defaultCountry.Code());
BString timeFormat;
if (status == B_OK)
status = fDefaultLocale.GetTimeFormat(timeFormat, false);
if (status == B_OK)
status = message->AddString("shortTimeFormat", timeFormat.String());
if (status == B_OK)
status = fDefaultLocale.GetTimeFormat(timeFormat, true);
if (status == B_OK)
status = message->AddString("longTimeFormat", timeFormat.String());
BFormattingConventions conventions;
fDefaultLocale.GetFormattingConventions(&conventions);
return status;
return conventions.Archive(message);
}
status_t
RosterData::_AddDefaultTimeZoneToMessage(BMessage* message) const
{
status_t status = message->AddString("timezone", fDefaultTimeZone.ID());
status_t status = message->AddString(kTimezoneField, fDefaultTimeZone.ID());
// add the offset, too, since that is used by clockconfig when setting
// up timezone state during boot
if (status == B_OK)
status = message->AddInt32("offset", fDefaultTimeZone.OffsetFromGMT());
if (status == B_OK) {
status = message->AddInt32(kOffsetField,
fDefaultTimeZone.OffsetFromGMT());
}
return status;
}
@@ -672,7 +614,7 @@ RosterData::_AddPreferredLanguagesToMessage(BMessage* message) const
BString langName;
for (int i = 0; fPreferredLanguages.FindString("language", i,
&langName) == B_OK; i++) {
status = message->AddString("language", langName);
status = message->AddString(kLanguageField, langName);
if (status != B_OK)
break;
}
@@ -699,16 +641,9 @@ MutableLocaleRoster::~MutableLocaleRoster()
status_t
MutableLocaleRoster::SetDefaultCountry(const BCountry& newCountry)
MutableLocaleRoster::SetDefaultFormattingConventions(const BFormattingConventions& newFormattingConventions)
{
return gRosterData.SetDefaultCountry(newCountry);
}
status_t
MutableLocaleRoster::SetDefaultLocale(const BLocale& newLocale)
{
return gRosterData.SetDefaultLocale(newLocale);
return gRosterData.SetDefaultFormattingConventions(newFormattingConventions);
}
@@ -726,22 +661,6 @@ MutableLocaleRoster::SetPreferredLanguages(const BMessage* languages)
}
status_t
MutableLocaleRoster::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;
}
status_t
MutableLocaleRoster::GetSystemCatalog(BCatalogAddOn** catalog) const
{
+4 -2
View File
@@ -190,11 +190,13 @@ TruncTimeBase(BString* result, int64 value, const View* view, float width)
time_t timeValue = (time_t)value;
if (be_locale->FormatDateTime(buffer, 256, timeValue, true) == B_OK)
if (be_locale->FormatDateTime(buffer, 256, timeValue, B_FULL_DATE_FORMAT,
B_MEDIUM_TIME_FORMAT) == B_OK)
resultWidth = view->StringWidth(buffer);
if (resultWidth > width
&& be_locale->FormatDateTime(buffer, 256, timeValue, false) == B_OK) {
&& be_locale->FormatDateTime(buffer, 256, timeValue,
B_SHORT_DATE_FORMAT, B_SHORT_TIME_FORMAT) == B_OK) {
resultWidth = view->StringWidth(buffer);
}
File diff suppressed because it is too large Load Diff
+25 -49
View File
@@ -7,11 +7,12 @@
#include <Box.h>
#include <Locale.h>
#include <FormattingConventions.h>
#include <String.h>
#include <View.h>
class BCheckBox;
class BCountry;
class BMenuField;
class BMessage;
@@ -20,79 +21,54 @@ class BStringView;
class BTextControl;
enum FormatSeparator {
kNoSeparator,
kSpaceSeparator,
kMinusSeparator,
kSlashSeparator,
kBackslashSeparator,
kDotSeparator,
kSeparatorsEnd
};
const uint32 kSettingsContentsModified = 'Scmo';
const uint32 kClockFormatChange = 'cfmc';
const uint32 kMenuMessage = 'FRMT';
static const uint32 kClockFormatChange = 'cfmc';
static const uint32 kStringsLanguageChange = 'strc';
class FormatView : public BView {
class FormatSettingsView : public BView {
public:
FormatView(const BLocale& locale);
~FormatView();
FormatSettingsView();
~FormatSettingsView();
virtual void MessageReceived(BMessage* message);
virtual void AttachedToWindow();
virtual void Revert();
virtual void SetLocale(const BLocale& locale);
virtual void RecordRevertSettings();
virtual bool IsRevertable() const;
virtual void Refresh(bool setInitial = false);
virtual bool IsReversible() const;
private:
void _UpdateExamples();
void _SendNotices();
void _ParseDateFormat();
void _ParseCurrencyFormat();
void _UpdateLongDateFormatString();
private:
BRadioButton* f24HrRadioButton;
BRadioButton* f12HrRadioButton;
BCheckBox* fUseLanguageStringsCheckBox;
BMenuField* fLongDateMenu[4];
BString fLongDateString[4];
BTextControl* fLongDateSeparator[4];
BMenuField* fDateMenu[3];
BString fDateString[3];
BMenuField* fSeparatorMenuField;
BRadioButton* f24HourRadioButton;
BRadioButton* f12HourRadioButton;
BStringView* fFullDateExampleView;
BStringView* fLongDateExampleView;
BStringView* fMediumDateExampleView;
BStringView* fShortDateExampleView;
BStringView* fFullTimeExampleView;
BStringView* fLongTimeExampleView;
BStringView* fMediumTimeExampleView;
BStringView* fShortTimeExampleView;
BStringView* fNumberFormatExampleView;
BStringView* fMonetaryView;
BTextControl* fCurrencySymbolView;
BRadioButton* fCurrencySymbolBefore;
BRadioButton* fCurrencySymbolAfter;
BStringView* fPositiveNumberExampleView;
BStringView* fNegativeNumberExampleView;
BStringView* fPositiveMonetaryExampleView;
BStringView* fNegativeMonetaryExampleView;
bool f24HrClock;
bool fLocaleIs24Hour;
FormatSeparator fSeparator;
BString fDateFormat;
BString fOriginalTimeFormat;
BString fOriginalLongTimeFormat;
bool fLocaleIs24Hr;
BLocale fLocale;
BFormattingConventions fInitialConventions;
BBox* fDateBox;
BBox* fTimeBox;
BBox* fNumbersBox;
BBox* fCurrencyBox;
BBox* fNumberBox;
BBox* fMonetaryBox;
};
-1
View File
@@ -6,7 +6,6 @@ UsePrivateHeaders shared ;
local sources =
LanguageListView.cpp
LocalePreflet.cpp
LocaleSettings.cpp
LocaleWindow.cpp
FormatSettingsView.cpp
;
+5 -6
View File
@@ -18,7 +18,8 @@
#include <Bitmap.h>
#include <Catalog.h>
#include <Country.h>
#include <FormattingConventions.h>
#include <LocaleRoster.h>
#include <Window.h>
@@ -30,17 +31,15 @@
LanguageListItem::LanguageListItem(const char* text, const char* id,
const char* code)
const char* code, const char* countryCode)
:
BStringItem(text),
fID(id),
fCode(code)
{
// TODO: should probably keep the BCountry as a member of the class
BCountry country(id);
fIcon = new(std::nothrow) BBitmap(BRect(0, 0, 15, 15), B_RGBA32);
if (fIcon != NULL && country.GetIcon(fIcon) != B_OK) {
if (fIcon != NULL && be_locale_roster->GetFlagIconForCountry(fIcon,
countryCode) != B_OK) {
delete fIcon;
fIcon = NULL;
}
+2 -1
View File
@@ -20,7 +20,8 @@
class LanguageListItem : public BStringItem {
public:
LanguageListItem(const char* text,
const char* id, const char* code);
const char* id, const char* langCode,
const char* countryCode = NULL);
LanguageListItem(const LanguageListItem& other);
virtual ~LanguageListItem();
+6 -38
View File
@@ -16,7 +16,6 @@
#include <Locale.h>
#include "LocalePreflet.h"
#include "LocaleSettings.h"
#include "LocaleWindow.h"
@@ -32,12 +31,9 @@ class LocalePreflet : public BApplication {
LocalePreflet();
virtual ~LocalePreflet();
virtual void MessageReceived(BMessage* message);
virtual void AboutRequested();
private:
LocaleSettings fSettings;
LocaleSettings fOriginalSettings;
LocaleWindow* fLocaleWindow;
};
@@ -51,52 +47,24 @@ LocalePreflet::LocalePreflet()
{
fLocaleWindow = new LocaleWindow();
fOriginalSettings.Load();
fSettings = fOriginalSettings;
/*
if (fSettings.Message().HasPoint("window_location")) {
BPoint point = fSettings.Message().FindPoint("window_location");
fLocaleWindow->MoveTo(point);
}
*/
fLocaleWindow->Show();
}
LocalePreflet::~LocalePreflet()
{
fSettings.Save();
}
void
LocalePreflet::MessageReceived(BMessage* message)
{
switch (message->what) {
case kMsgSettingsChanged:
fSettings.UpdateFrom(message);
break;
case kMsgRevert:
fSettings = fOriginalSettings;
break;
default:
BApplication::MessageReceived(message);
break;
}
}
void
LocalePreflet::AboutRequested()
{
const char* authors[3];
authors[0] = "Axel Dörfler";
authors[1] = "Adrien Destugues";
authors[2] = NULL;
const char* authors[] = {
"Axel Dörfler",
"Adrien Destugues",
"Oliver Tappe",
NULL
};
BAboutWindow about(B_TRANSLATE("Locale"), 2005, authors);
about.Show();
}
-108
View File
@@ -1,108 +0,0 @@
/*
* Copyright 2010, Adrien Destugues <pulkomandy@pulkomandy.ath.cx>.
* Distributed under the terms of the MIT License.
*/
#include "LocaleSettings.h"
#include <FindDirectory.h>
#include <Locale.h>
#include <MutableLocaleRoster.h>
#include <Path.h>
#include <String.h>
#include <SupportDefs.h>
using BPrivate::gMutableLocaleRoster;
static const uint32 kMsgLocaleSettings = 'LCst';
LocaleSettings::LocaleSettings()
:
fMessage(kMsgLocaleSettings)
{
// Set default preferences
fMessage.AddString("language", "en");
fMessage.AddString("country", "en_US");
}
status_t
LocaleSettings::Load()
{
BFile file;
status_t err;
err = _Open(&file, B_READ_ONLY);
if (err != B_OK)
return err;
return fMessage.Unflatten(&file);
}
status_t
LocaleSettings::Save()
{
return B_OK;
}
status_t
LocaleSettings::_Open(BFile* file, int32 mode)
{
BPath path;
if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK)
return B_ERROR;
path.Append("Locale settings");
return file->SetTo(path.Path(), mode);
}
void
LocaleSettings::UpdateFrom(BMessage* message)
{
BString messageContent;
BLocale locale(*be_locale);
if (message->FindString("language", &messageContent) == B_OK) {
fMessage.RemoveName("language");
for (int i = 0;; i++) {
if (message->FindString("language", i, &messageContent) != B_OK)
break;
fMessage.AddString("language", messageContent);
}
gMutableLocaleRoster->SetPreferredLanguages(message);
}
bool localeChanged = false;
if (message->FindString("country", &messageContent) == B_OK) {
fMessage.ReplaceString("country", messageContent);
fMessage.RemoveName("shortTimeFormat");
fMessage.RemoveName("longTimeFormat");
locale.SetCountry(messageContent.String());
localeChanged = true;
}
if (message->FindString("shortTimeFormat", &messageContent) == B_OK) {
fMessage.RemoveName("shortTimeFormat");
fMessage.AddString("shortTimeFormat", messageContent);
locale.SetTimeFormat(messageContent, false);
localeChanged = true;
}
if (message->FindString("longTimeFormat", &messageContent) == B_OK) {
fMessage.RemoveName("longTimeFormat");
fMessage.AddString("longTimeFormat", messageContent);
locale.SetTimeFormat(messageContent, true);
localeChanged = true;
}
if (localeChanged)
gMutableLocaleRoster->SetDefaultLocale(locale);
}
-50
View File
@@ -1,50 +0,0 @@
/*
* Copyright 2010, Adrien Destugues <pulkomandy@pulkomandy.ath.cx>.
* Distributed under the terms of the MIT License.
*/
#ifndef __LOCALE_SETTINGS_H__
#define __LOCALE_SETTINGS_H__
#include <File.h>
#include <Message.h>
class LocaleSettings {
public:
LocaleSettings();
status_t Load();
status_t Save();
bool operator==(const LocaleSettings& other);
void UpdateFrom(BMessage* message);
/*
void SetPreferredLanguages();
void GetPreferredLanguages();
void SetCountry();
void GetCountry();
void SetDateFormat();
void GetDateFormat();
void SetTimeFormat();
void GetTimeFormat();
void SetNumberFormat();
void GetNumberFormat();
void SetMoneyFormat();
void GetMoneyFormat();
*/
private:
status_t _Open(BFile* file, int32 mode);
BMessage fMessage;
};
#endif
+168 -107
View File
@@ -14,10 +14,11 @@
#include <Button.h>
#include <Catalog.h>
#include <ControlLook.h>
#include <FormattingConventions.h>
#include <GroupLayout.h>
#include <LayoutBuilder.h>
#include <Locale.h>
#include <LocaleRoster.h>
#include <MutableLocaleRoster.h>
#include <Screen.h>
#include <ScrollView.h>
#include <StringView.h>
@@ -29,7 +30,7 @@
#include "LanguageListView.h"
#include <stdio.h>
using BPrivate::gMutableLocaleRoster;
#undef B_TRANSLATE_CONTEXT
@@ -41,7 +42,7 @@ static const uint32 kMsgLanguageDragged = 'LaDr';
static const uint32 kMsgPreferredLanguageInvoked = 'PLIv';
static const uint32 kMsgPreferredLanguageDragged = 'PLDr';
static const uint32 kMsgPreferredLanguageDeleted = 'PLDl';
static const uint32 kMsgCountrySelection = 'csel';
static const uint32 kMsgConventionsSelection = 'csel';
static const uint32 kMsgDefaults = 'dflt';
static const uint32 kMsgPreferredLanguagesChanged = 'lang';
@@ -59,26 +60,15 @@ compare_typed_list_items(const BListItem* _a, const BListItem* _b)
}
static int
compare_void_list_items(const void* _a, const void* _b)
{
static BCollator collator;
LanguageListItem* a = *(LanguageListItem**)_a;
LanguageListItem* b = *(LanguageListItem**)_b;
return collator.Compare(a->Text(), b->Text());
}
// #pragma mark -
LocaleWindow::LocaleWindow()
:
BWindow(BRect(0, 0, 0, 0), B_TRANSLATE("Locale"), B_TITLED_WINDOW,
B_QUIT_ON_WINDOW_CLOSE | B_ASYNCHRONOUS_CONTROLS
| B_AUTO_UPDATE_SIZE_LIMITS)
| B_AUTO_UPDATE_SIZE_LIMITS),
fInitialConventionsItem(NULL),
fDefaultConventionsItem(NULL)
{
SetLayout(new BGroupLayout(B_HORIZONTAL));
@@ -92,7 +82,7 @@ LocaleWindow::LocaleWindow()
fLanguageListView = new LanguageListView("available",
B_MULTIPLE_SELECTION_LIST);
BScrollView* scrollView = new BScrollView("scroller", fLanguageListView,
B_WILL_DRAW | B_FRAME_EVENTS, false, true);
B_WILL_DRAW | B_FRAME_EVENTS, true, true);
fLanguageListView->SetInvocationMessage(new BMessage(kMsgLanguageInvoked));
fLanguageListView->SetDragMessage(new BMessage(kMsgLanguageDragged));
@@ -101,12 +91,12 @@ LocaleWindow::LocaleWindow()
fLanguageListView->GetFont(&font);
// Fill the language list from the LocaleRoster data
BMessage installedLanguages;
if (be_locale_roster->GetAvailableLanguages(&installedLanguages) == B_OK) {
BMessage availableLanguages;
if (be_locale_roster->GetAvailableLanguages(&availableLanguages) == B_OK) {
BString currentID;
LanguageListItem* lastAddedCountryItem = NULL;
for (int i = 0; installedLanguages.FindString("language", i, &currentID)
for (int i = 0; availableLanguages.FindString("language", i, &currentID)
== B_OK; i++) {
// Now get the human-readable, native name for each language
BString name;
@@ -126,7 +116,8 @@ LocaleWindow::LocaleWindow()
}
LanguageListItem* item = new LanguageListItem(name,
currentID.String(), currentLanguage.Code());
currentID.String(), currentLanguage.Code(),
currentLanguage.CountryCode());
if (currentLanguage.IsCountrySpecific()
&& lastAddedCountryItem != NULL
&& lastAddedCountryItem->Code() == item->Code()) {
@@ -155,7 +146,7 @@ LocaleWindow::LocaleWindow()
fPreferredListView = new LanguageListView("preferred",
B_MULTIPLE_SELECTION_LIST);
BScrollView* scrollViewEnabled = new BScrollView("scroller",
fPreferredListView, B_WILL_DRAW | B_FRAME_EVENTS, false, true);
fPreferredListView, B_WILL_DRAW | B_FRAME_EVENTS, true, true);
fPreferredListView->SetInvocationMessage(
new BMessage(kMsgPreferredLanguageInvoked));
@@ -178,40 +169,60 @@ LocaleWindow::LocaleWindow()
BView* countryTab = new BView(B_TRANSLATE("Formatting"), B_WILL_DRAW);
countryTab->SetLayout(new BGroupLayout(B_VERTICAL, 0));
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));
fConventionsListView = new LanguageListView("formatting",
B_SINGLE_SELECTION_LIST);
scrollView = new BScrollView("scroller", fConventionsListView,
B_WILL_DRAW | B_FRAME_EVENTS, true, true);
fConventionsListView->SetSelectionMessage(
new BMessage(kMsgConventionsSelection));
// get all available formatting conventions (by language)
BString formattingConventionCode;
LanguageListItem* currentItem = NULL;
BCountry defaultFormattingConvention;
be_locale->GetCountry(&defaultFormattingConvention);
BFormattingConventions defaultConventions;
be_locale->GetFormattingConventions(&defaultConventions);
BString conventionID;
fInitialConventionsItem = NULL;
LanguageListItem* lastAddedConventionsItem = NULL;
for (int i = 0;
installedLanguages.FindString("language", i, &formattingConventionCode)
== B_OK; i++) {
BCountry formattingConvention(formattingConventionCode);
BString formattingConventionName;
formattingConvention.GetName(formattingConventionName);
availableLanguages.FindString("language", i, &conventionID) == B_OK;
i++) {
BFormattingConventions convention(conventionID);
BString conventionName;
convention.GetName(conventionName);
LanguageListItem* item = new LanguageListItem(formattingConventionName,
formattingConventionCode, NULL);
listView->AddItem(item);
if (!strcmp(formattingConventionCode,
defaultFormattingConvention.Code()))
currentItem = item;
LanguageListItem* item = new LanguageListItem(conventionName,
conventionID, convention.LanguageCode(), convention.CountryCode());
if (!strcmp(conventionID, "en_US"))
fDefaultConventionsItem = item;
if (conventionID.FindFirst('_') >= 0
&& lastAddedConventionsItem != NULL
&& lastAddedConventionsItem->Code() == item->Code()) {
if (!strcmp(conventionID, defaultConventions.ID())) {
lastAddedConventionsItem->SetExpanded(true);
fInitialConventionsItem = item;
}
fConventionsListView->AddUnder(item, lastAddedConventionsItem);
} else {
// This conventions-item isn't country-specific, add it at top-level
fConventionsListView->AddItem(item);
if (conventionID.FindFirst('_') < 0) {
item->SetExpanded(false);
lastAddedConventionsItem = item;
}
if (!strcmp(conventionID, defaultConventions.ID()))
fInitialConventionsItem = item;
}
}
listView->SortItems(compare_void_list_items);
if (currentItem != NULL)
listView->Select(listView->IndexOf(currentItem));
fConventionsListView->FullListSortItems(compare_typed_list_items);
if (fInitialConventionsItem != NULL) {
fConventionsListView->Select(fConventionsListView->IndexOf(
fInitialConventionsItem));
}
// TODO: find a real solution intead of this hack
listView->SetExplicitMinSize(
BSize(25 * be_plain_font->Size(), B_SIZE_UNSET));
fConventionsListView->SetExplicitMinSize(BSize(20 * be_plain_font->Size(),
B_SIZE_UNSET));
fFormatView = new FormatView(*be_locale);
fFormatView = new FormatSettingsView();
countryTab->AddChild(BLayoutBuilder::Group<>(B_HORIZONTAL, spacing)
.AddGroup(B_VERTICAL, 3)
@@ -220,16 +231,14 @@ LocaleWindow::LocaleWindow()
.Add(fFormatView)
.SetInsets(spacing, spacing, spacing, spacing));
listView->ScrollToSelection();
tabView->AddTab(languageTab);
tabView->AddTab(countryTab);
BButton* button = new BButton(B_TRANSLATE("Defaults"),
new BMessage(kMsgDefaults));
BButton* button
= new BButton(B_TRANSLATE("Defaults"), new BMessage(kMsgDefaults));
fRevertButton = new BButton(B_TRANSLATE("Revert"),
new BMessage(kMsgRevert));
fRevertButton
= new BButton(B_TRANSLATE("Revert"), new BMessage(kMsgRevert));
fRevertButton->SetEnabled(false);
BLayoutBuilder::Group<>(this, B_VERTICAL, spacing)
@@ -242,8 +251,8 @@ LocaleWindow::LocaleWindow()
.SetInsets(spacing, spacing, spacing, spacing)
.End();
_UpdatePreferredFromLocaleRoster();
SettingsReverted();
_Refresh(true);
_SettingsReverted();
CenterOnScreen();
}
@@ -262,8 +271,25 @@ LocaleWindow::MessageReceived(BMessage* message)
break;
case kMsgRevert:
be_app_messenger.SendMessage(message);
_UpdatePreferredFromLocaleRoster();
{
_Revert();
fFormatView->Revert();
fConventionsListView->DeselectAll();
if (fInitialConventionsItem != NULL) {
BListItem* superitem
= fConventionsListView->Superitem(fInitialConventionsItem);
if (superitem != NULL)
superitem->SetExpanded(true);
fConventionsListView->Select(fConventionsListView->IndexOf(
fInitialConventionsItem));
fConventionsListView->ScrollToSelection();
}
_SettingsReverted();
break;
}
case kMsgSettingsChanged:
_SettingsChanged();
break;
case kMsgLanguageDragged:
@@ -342,7 +368,7 @@ LocaleWindow::MessageReceived(BMessage* message)
break;
}
case kMsgCountrySelection:
case kMsgConventionsSelection:
{
// Country selection changed.
// Get the new selected country from the ListView and send it to the
@@ -351,18 +377,15 @@ LocaleWindow::MessageReceived(BMessage* message)
if (message->FindPointer("source", &listView) != B_OK)
break;
BListView* countryList = static_cast<BListView*>(listView);
BListView* conventionsList = static_cast<BListView*>(listView);
LanguageListItem* item = static_cast<LanguageListItem*>
(countryList->ItemAt(countryList->CurrentSelection()));
BMessage newMessage(kMsgSettingsChanged);
newMessage.AddString("country", item->ID());
be_app_messenger.SendMessage(&newMessage);
SettingsChanged();
(conventionsList->ItemAt(conventionsList->CurrentSelection()));
BFormattingConventions conventions(item->ID());
gMutableLocaleRoster->SetDefaultFormattingConventions(conventions);
BCountry country(item->ID());
BLocale locale(NULL, &country);
fFormatView->SetLocale(locale);
_SettingsChanged();
fFormatView->Refresh();
break;
}
@@ -381,35 +404,57 @@ LocaleWindow::QuitRequested()
void
LocaleWindow::SettingsChanged()
LocaleWindow::Show()
{
fRevertButton->SetEnabled(true);
BWindow::Show();
Lock();
if (IsLocked()) {
fConventionsListView->ScrollToSelection();
Unlock();
}
}
void
LocaleWindow::SettingsReverted()
LocaleWindow::_SettingsChanged()
{
bool haveAnythingToRevert = fFormatView->IsReversible() || _IsReversible();
fRevertButton->SetEnabled(haveAnythingToRevert);
}
void
LocaleWindow::_SettingsReverted()
{
fRevertButton->SetEnabled(false);
}
bool
LocaleWindow::_IsReversible() const
{
BMessage preferredLanguages;
be_locale_roster->GetPreferredLanguages(&preferredLanguages);
return !preferredLanguages.HasSameData(fInitialPreferredLanguages);
}
void
LocaleWindow::_PreferredLanguagesChanged()
{
BMessage update(kMsgSettingsChanged);
BMessage preferredLanguages;
int index = 0;
while (index < fPreferredListView->FullListCountItems()) {
// only include subitems: we can guess the superitem
// from them anyway
// only include subitems: we can guess the superitem from them anyway
LanguageListItem* item = static_cast<LanguageListItem*>(
fPreferredListView->FullListItemAt(index));
if (item != NULL)
update.AddString("language", item->ID());
preferredLanguages.AddString("language", item->ID());
index++;
}
be_app_messenger.SendMessage(&update);
gMutableLocaleRoster->SetPreferredLanguages(&preferredLanguages);
_EnableDisableLanguages();
}
@@ -437,15 +482,31 @@ LocaleWindow::_EnableDisableLanguages()
}
}
SettingsChanged();
EnableUpdates();
}
//! Get the preferred languages from the settings.
void
LocaleWindow::_UpdatePreferredFromLocaleRoster()
LocaleWindow::_Refresh(bool setInitial)
{
BMessage preferredLanguages;
be_locale_roster->GetPreferredLanguages(&preferredLanguages);
if (setInitial)
fInitialPreferredLanguages = preferredLanguages;
_SetPreferredLanguages(preferredLanguages);
}
void
LocaleWindow::_Revert()
{
_SetPreferredLanguages(fInitialPreferredLanguages);
}
void
LocaleWindow::_SetPreferredLanguages(const BMessage& languages)
{
DisableUpdates();
@@ -455,17 +516,12 @@ LocaleWindow::_UpdatePreferredFromLocaleRoster()
}
fPreferredListView->MakeEmpty();
// Add new ones from the locale roster
BMessage preferredLanguages;
be_locale_roster->GetPreferredLanguages(&preferredLanguages);
BString languageID;
for (int32 index = 0; preferredLanguages.FindString("language", index,
&languageID) == B_OK; index++) {
for (int32 index = 0;
languages.FindString("language", index, &languageID) == B_OK; index++) {
int32 listIndex;
LanguageListItem* item
= fLanguageListView->ItemForLanguageID(languageID.String(),
&listIndex);
LanguageListItem* item = fLanguageListView->ItemForLanguageID(
languageID.String(), &listIndex);
if (item != NULL) {
// We found the item we were looking for, now copy it to
// the other list
@@ -488,22 +544,15 @@ LocaleWindow::_InsertPreferredLanguage(LanguageListItem* item, int32 atIndex)
if (atIndex == -1)
atIndex = fPreferredListView->CountItems();
BLanguage* language = NULL;
be_locale_roster->GetLanguage(item->Code(), &language);
LanguageListItem* baseItem = NULL;
if (language != NULL) {
baseItem = fPreferredListView->ItemForLanguageCode(language->Code(),
&atIndex);
delete language;
}
BLanguage language(item->Code());
LanguageListItem* baseItem
= fPreferredListView->ItemForLanguageCode(language.Code(), &atIndex);
DisableUpdates();
fPreferredListView->AddItem(new LanguageListItem(*item), atIndex);
// Replace other languages with the same base
// Replace other languages sharing the same base
if (baseItem != NULL) {
fPreferredListView->RemoveItem(baseItem);
delete baseItem;
@@ -518,11 +567,23 @@ LocaleWindow::_InsertPreferredLanguage(LanguageListItem* item, int32 atIndex)
void
LocaleWindow::_Defaults()
{
BMessage update(kMsgSettingsChanged);
update.AddString("language", "en");
BMessage preferredLanguages;
preferredLanguages.AddString("language", "en");
gMutableLocaleRoster->SetPreferredLanguages(&preferredLanguages);
_SetPreferredLanguages(preferredLanguages);
be_app_messenger.SendMessage(&update);
SettingsChanged();
_UpdatePreferredFromLocaleRoster();
BFormattingConventions conventions("en_US");
gMutableLocaleRoster->SetDefaultFormattingConventions(conventions);
fConventionsListView->DeselectAll();
if (fDefaultConventionsItem != NULL) {
BListItem* superitem
= fConventionsListView->Superitem(fDefaultConventionsItem);
if (superitem != NULL && !superitem->IsExpanded())
superitem->SetExpanded(true);
fConventionsListView->Select(fConventionsListView->IndexOf(
fDefaultConventionsItem));
fConventionsListView->ScrollToSelection();
}
}
+18 -6
View File
@@ -6,6 +6,7 @@
#define LOCALE_WINDOW_H
#include <Message.h>
#include <Window.h>
@@ -14,7 +15,7 @@ static const uint32 kMsgRevert = 'revt';
class BButton;
class BListView;
class FormatView;
class FormatSettingsView;
class LanguageListItem;
class LanguageListView;
@@ -26,14 +27,21 @@ public:
virtual void MessageReceived(BMessage* message);
virtual bool QuitRequested();
void SettingsChanged();
void SettingsReverted();
virtual void Show();
private:
void _SettingsChanged();
void _SettingsReverted();
bool _IsReversible() const;
void _Refresh(bool setInitial = false);
void _Revert();
void _SetPreferredLanguages(
const BMessage& languages);
void _PreferredLanguagesChanged();
void _EnableDisableLanguages();
void _UpdatePreferredFromLocaleRoster();
void _InsertPreferredLanguage(LanguageListItem* item,
int32 atIndex = -1);
void _Defaults();
@@ -41,7 +49,11 @@ private:
BButton* fRevertButton;
LanguageListView* fLanguageListView;
LanguageListView* fPreferredListView;
FormatView* fFormatView;
LanguageListView* fConventionsListView;
FormatSettingsView* fFormatView;
LanguageListItem* fInitialConventionsItem;
LanguageListItem* fDefaultConventionsItem;
BMessage fInitialPreferredLanguages;
};
+6 -4
View File
@@ -277,8 +277,9 @@ void
TTimeEdit::_UpdateFields()
{
time_t time = fTime.Time_t();
be_locale->FormatTime(&fText, fFieldPositions, fFieldPosCount, time, true);
be_locale->GetTimeFields(fFields, fFieldCount, true);
be_locale->FormatTime(&fText, fFieldPositions, fFieldPosCount, time,
B_MEDIUM_TIME_FORMAT);
be_locale->GetTimeFields(fFields, fFieldCount, B_MEDIUM_TIME_FORMAT);
}
@@ -675,8 +676,9 @@ void
TDateEdit::_UpdateFields()
{
time_t time = BDateTime(fDate, BTime()).Time_t();
be_locale->FormatDate(&fText, fFieldPositions, fFieldPosCount, time, false);
be_locale->GetDateFields(fFields, fFieldCount, false);
be_locale->FormatDate(&fText, fFieldPositions, fFieldPosCount, time,
B_SHORT_DATE_FORMAT);
be_locale->GetDateFields(fFields, fFieldCount, B_SHORT_DATE_FORMAT);
}
+6 -4
View File
@@ -184,10 +184,12 @@ TimeZoneView::GetToolTipAt(BPoint point, BToolTip** _tip)
BString nowInTimeZone;
time_t now = time(NULL);
be_locale->FormatTime(&nowInTimeZone, now, false, &item->TimeZone());
be_locale->FormatTime(&nowInTimeZone, now, B_SHORT_TIME_FORMAT,
&item->TimeZone());
BString dateInTimeZone;
be_locale->FormatDate(&dateInTimeZone, now, false, &item->TimeZone());
be_locale->FormatDate(&dateInTimeZone, now, B_SHORT_DATE_FORMAT,
&item->TimeZone());
BString toolTip = item->Text();
toolTip << '\n' << item->TimeZone().ShortName() << " / "
@@ -300,7 +302,7 @@ TimeZoneView::_BuildZoneMenu()
BString countryCode;
for (int c = 0; countryList.FindString("country", c, &countryCode)
== B_OK; c++) {
BCountry country("", countryCode);
BCountry country(countryCode);
BString countryName;
country.GetName(countryName);
@@ -532,7 +534,7 @@ TimeZoneView::_FormatTime(const BTimeZone& timeZone)
: 0;
now -= timeZone.OffsetFromGMT() - currentOffset;
}
be_locale->FormatTime(&result, now, false, &timeZone);
be_locale->FormatTime(&result, now, B_SHORT_TIME_FORMAT, &timeZone);
return result;
}