* Add FormatDate variant returning fields positions and associated DateFields returning their identifiers
* Use them in the time preflet to display and edit the date in a local-aware way git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@37551 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
a636d1e365
commit
7af097b973
@ -21,11 +21,14 @@ enum {
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
B_INVALID = B_BAD_DATA,
|
||||
B_AM_PM = 0,
|
||||
B_HOUR,
|
||||
B_MINUTE,
|
||||
B_SECOND
|
||||
B_DATE_ELEMENT_INVALID = B_BAD_DATA,
|
||||
B_DATE_ELEMENT_YEAR = 0,
|
||||
B_DATE_ELEMENT_MONTH,
|
||||
B_DATE_ELEMENT_DAY,
|
||||
B_DATE_ELEMENT_AM_PM,
|
||||
B_DATE_ELEMENT_HOUR,
|
||||
B_DATE_ELEMENT_MINUTE,
|
||||
B_DATE_ELEMENT_SECOND
|
||||
} BDateElement;
|
||||
|
||||
|
||||
@ -47,6 +50,9 @@ class BCountry {
|
||||
bool longFormat);
|
||||
virtual void FormatDate(BString* string, time_t time,
|
||||
bool longFormat);
|
||||
status_t FormatDate(BString* string, int*& fieldPositions,
|
||||
int& fieldCount, time_t time, bool longFormat);
|
||||
|
||||
virtual void FormatTime(char* string, size_t maxSize, time_t time,
|
||||
bool longFormat);
|
||||
virtual void FormatTime(BString* string, time_t time,
|
||||
@ -55,6 +61,8 @@ class BCountry {
|
||||
int& fieldCount, time_t time, bool longFormat);
|
||||
status_t TimeFields(BDateElement*& fields, int& fieldCount,
|
||||
bool longFormat);
|
||||
status_t DateFields(BDateElement*& fields, int& fieldCount,
|
||||
bool longFormat);
|
||||
|
||||
bool DateFormat(BString&, bool longFormat) const;
|
||||
void SetDateFormat(const char* formatString,
|
||||
@ -62,8 +70,6 @@ class BCountry {
|
||||
void SetTimeFormat(const char* formatString,
|
||||
bool longFormat = true);
|
||||
bool TimeFormat(BString&, bool longFormat) const;
|
||||
const char* DateSeparator() const;
|
||||
const char* TimeSeparator() const;
|
||||
|
||||
int StartOfWeek();
|
||||
|
||||
@ -103,7 +109,6 @@ class BCountry {
|
||||
icu_44::DateFormat* fICUShortDateFormatter;
|
||||
icu_44::DateFormat* fICULongTimeFormatter;
|
||||
icu_44::DateFormat* fICUShortTimeFormatter;
|
||||
const char** fStrings;
|
||||
icu_44::Locale* fICULocale;
|
||||
};
|
||||
|
||||
|
@ -35,29 +35,7 @@ using BPrivate::B_WEEK_START_MONDAY;
|
||||
using BPrivate::B_WEEK_START_SUNDAY;
|
||||
|
||||
|
||||
const char* gStrings[] = {
|
||||
// date/time format
|
||||
"",
|
||||
"",
|
||||
// short date/time format
|
||||
"",
|
||||
"",
|
||||
// am/pm string
|
||||
"AM",
|
||||
"PM",
|
||||
// separators
|
||||
".",
|
||||
":",
|
||||
|
||||
// currency/monetary
|
||||
"."
|
||||
","
|
||||
};
|
||||
|
||||
|
||||
BCountry::BCountry(const char* languageCode, const char* countryCode)
|
||||
:
|
||||
fStrings(gStrings)
|
||||
{
|
||||
fICULocale = new ICU_VERSION::Locale(languageCode, countryCode);
|
||||
fICULongDateFormatter = DateFormat::createDateInstance(
|
||||
@ -72,8 +50,6 @@ BCountry::BCountry(const char* languageCode, const char* countryCode)
|
||||
|
||||
|
||||
BCountry::BCountry(const char* languageAndCountryCode)
|
||||
:
|
||||
fStrings(gStrings)
|
||||
{
|
||||
fICULocale = new ICU_VERSION::Locale(languageAndCountryCode);
|
||||
fICULongDateFormatter = DateFormat::createDateInstance(
|
||||
@ -138,17 +114,6 @@ BCountry::GetIcon(BBitmap* result)
|
||||
}
|
||||
|
||||
|
||||
// TODO use ICU backend keywords instead
|
||||
const char*
|
||||
BCountry::GetString(uint32 id) const
|
||||
{
|
||||
if (id < B_COUNTRY_STRINGS_BASE || id >= B_NUM_COUNTRY_STRINGS)
|
||||
return NULL;
|
||||
|
||||
return gStrings[id - B_COUNTRY_STRINGS_BASE];
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BCountry::FormatDate(char* string, size_t maxSize, time_t time, bool longFormat)
|
||||
{
|
||||
@ -175,6 +140,45 @@ BCountry::FormatDate(BString *string, time_t time, bool longFormat)
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BCountry::FormatDate(BString* string, int*& fieldPositions, int& fieldCount,
|
||||
time_t time, bool longFormat)
|
||||
{
|
||||
fieldPositions = NULL;
|
||||
UErrorCode error = U_ZERO_ERROR;
|
||||
ICU_VERSION::DateFormat* dateFormatter;
|
||||
ICU_VERSION::FieldPositionIterator positionIterator;
|
||||
dateFormatter = longFormat ? fICULongDateFormatter : fICUShortDateFormatter;
|
||||
UnicodeString ICUString;
|
||||
ICUString = dateFormatter->format((UDate)time * 1000, ICUString,
|
||||
&positionIterator, error);
|
||||
|
||||
if (error != U_ZERO_ERROR)
|
||||
return B_ERROR;
|
||||
|
||||
ICU_VERSION::FieldPosition field;
|
||||
std::vector<int> fieldPosStorage;
|
||||
fieldCount = 0;
|
||||
while (positionIterator.next(field)) {
|
||||
fieldPosStorage.push_back(field.getBeginIndex());
|
||||
fieldPosStorage.push_back(field.getEndIndex());
|
||||
fieldCount += 2;
|
||||
}
|
||||
|
||||
fieldPositions = (int*) malloc(fieldCount * sizeof(int));
|
||||
|
||||
for (int i = 0 ; i < fieldCount ; i++ )
|
||||
fieldPositions[i] = fieldPosStorage[i];
|
||||
|
||||
string->Truncate(0);
|
||||
BStringByteSink stringConverter(string);
|
||||
|
||||
ICUString.toUTF8(stringConverter);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BCountry::FormatTime(char* string, size_t maxSize, time_t time, bool longFormat)
|
||||
{
|
||||
@ -272,21 +276,66 @@ BCountry::TimeFields(BDateElement*& fields, int& fieldCount, bool longFormat)
|
||||
case UDAT_HOUR_OF_DAY0_FIELD:
|
||||
case UDAT_HOUR1_FIELD:
|
||||
case UDAT_HOUR0_FIELD:
|
||||
fields[i] = B_HOUR;
|
||||
fields[i] = B_DATE_ELEMENT_HOUR;
|
||||
break;
|
||||
case UDAT_MINUTE_FIELD:
|
||||
fields[i] = B_MINUTE;
|
||||
fields[i] = B_DATE_ELEMENT_MINUTE;
|
||||
break;
|
||||
case UDAT_SECOND_FIELD:
|
||||
fields[i] = B_SECOND;
|
||||
fields[i] = B_DATE_ELEMENT_SECOND;
|
||||
break;
|
||||
case UDAT_AM_PM_FIELD:
|
||||
fields[i] = B_AM_PM;
|
||||
fields[i] = B_DATE_ELEMENT_AM_PM;
|
||||
break;
|
||||
default:
|
||||
std::cout << "invalid field id " << fieldPosStorage[i]
|
||||
<< std::endl;
|
||||
fields[i] = B_INVALID;
|
||||
fields[i] = B_DATE_ELEMENT_INVALID;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BCountry::DateFields(BDateElement*& fields, int& fieldCount, bool longFormat)
|
||||
{
|
||||
fields = NULL;
|
||||
UErrorCode error = U_ZERO_ERROR;
|
||||
ICU_VERSION::DateFormat* dateFormatter;
|
||||
ICU_VERSION::FieldPositionIterator positionIterator;
|
||||
dateFormatter = longFormat ? fICULongDateFormatter : fICUShortDateFormatter;
|
||||
UnicodeString ICUString;
|
||||
time_t now;
|
||||
ICUString = dateFormatter->format((UDate)time(&now) * 1000, ICUString,
|
||||
&positionIterator, error);
|
||||
|
||||
if (error != U_ZERO_ERROR)
|
||||
return B_ERROR;
|
||||
|
||||
ICU_VERSION::FieldPosition field;
|
||||
std::vector<int> fieldPosStorage;
|
||||
fieldCount = 0;
|
||||
while (positionIterator.next(field)) {
|
||||
fieldPosStorage.push_back(field.getField());
|
||||
fieldCount ++;
|
||||
}
|
||||
|
||||
fields = (BDateElement*) malloc(fieldCount * sizeof(BDateElement));
|
||||
|
||||
for (int i = 0 ; i < fieldCount ; i++ ) {
|
||||
switch (fieldPosStorage[i]) {
|
||||
case UDAT_YEAR_FIELD:
|
||||
fields[i] = B_DATE_ELEMENT_YEAR;
|
||||
break;
|
||||
case UDAT_MONTH_FIELD:
|
||||
fields[i] = B_DATE_ELEMENT_MONTH;
|
||||
break;
|
||||
case UDAT_DATE_FIELD:
|
||||
fields[i] = B_DATE_ELEMENT_DAY;
|
||||
break;
|
||||
default:
|
||||
fields[i] = B_DATE_ELEMENT_INVALID;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -376,23 +425,6 @@ BCountry::StartOfWeek()
|
||||
}
|
||||
|
||||
|
||||
// TODO find how to get it from ICU (setting it is ok, we use the pattern-string
|
||||
// for that)
|
||||
// Or remove this function ?
|
||||
const char*
|
||||
BCountry::DateSeparator() const
|
||||
{
|
||||
return fStrings[B_DATE_SEPARATOR];
|
||||
}
|
||||
|
||||
|
||||
const char*
|
||||
BCountry::TimeSeparator() const
|
||||
{
|
||||
return fStrings[B_TIME_SEPARATOR];
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BCountry::FormatNumber(char* string, size_t maxSize, double value)
|
||||
{
|
||||
|
@ -121,7 +121,7 @@ TTimeEdit::DrawSection(uint32 index, bool hasFocus)
|
||||
free(fieldPositions);
|
||||
|
||||
// calc and center text in section rect
|
||||
float width = be_plain_font->StringWidth(field.String());
|
||||
float width = be_plain_font->StringWidth(field);
|
||||
|
||||
BPoint offset(-((bounds.Width()- width) / 2.0) -1.0,
|
||||
bounds.Height() / 2.0 -6.0);
|
||||
@ -280,13 +280,13 @@ TTimeEdit::BuildDispatch(BMessage *message)
|
||||
data = fHoldValue;
|
||||
|
||||
switch(dateFormat[index]) {
|
||||
case B_HOUR:
|
||||
case B_DATE_ELEMENT_HOUR:
|
||||
message->AddInt32(fields[0], data);
|
||||
break;
|
||||
case B_MINUTE:
|
||||
case B_DATE_ELEMENT_MINUTE:
|
||||
message->AddInt32(fields[1], data);
|
||||
break;
|
||||
case B_SECOND:
|
||||
case B_DATE_ELEMENT_SECOND:
|
||||
message->AddInt32(fields[2], data);
|
||||
default:
|
||||
break;
|
||||
@ -311,7 +311,7 @@ TTimeEdit::_CheckRange()
|
||||
return;
|
||||
}
|
||||
switch (fields[fFocus]) {
|
||||
case B_HOUR:
|
||||
case B_DATE_ELEMENT_HOUR:
|
||||
if (value > 23)
|
||||
value = 0;
|
||||
else if (value < 0)
|
||||
@ -320,7 +320,7 @@ TTimeEdit::_CheckRange()
|
||||
fTime.SetTime(value, fTime.Minute(), fTime.Second());
|
||||
break;
|
||||
|
||||
case B_MINUTE:
|
||||
case B_DATE_ELEMENT_MINUTE:
|
||||
if (value> 59)
|
||||
value = 0;
|
||||
else if (value < 0)
|
||||
@ -329,7 +329,7 @@ TTimeEdit::_CheckRange()
|
||||
fTime.SetTime(fTime.Hour(), value, fTime.Second());
|
||||
break;
|
||||
|
||||
case B_SECOND:
|
||||
case B_DATE_ELEMENT_SECOND:
|
||||
if (value > 59)
|
||||
value = 0;
|
||||
else if (value < 0)
|
||||
@ -338,7 +338,7 @@ TTimeEdit::_CheckRange()
|
||||
fTime.SetTime(fTime.Hour(), fTime.Minute(), value);
|
||||
break;
|
||||
|
||||
case B_AM_PM:
|
||||
case B_DATE_ELEMENT_AM_PM:
|
||||
value = fTime.Hour();
|
||||
if (value < 13)
|
||||
value += 12;
|
||||
@ -377,17 +377,17 @@ TTimeEdit::_IsValidDoubleDigi(int32 value)
|
||||
return false;
|
||||
}
|
||||
switch (fields[fFocus]) {
|
||||
case B_HOUR:
|
||||
case B_DATE_ELEMENT_HOUR:
|
||||
if (value <= 23)
|
||||
isInRange = true;
|
||||
break;
|
||||
|
||||
case B_MINUTE:
|
||||
case B_DATE_ELEMENT_MINUTE:
|
||||
if (value <= 59)
|
||||
isInRange = true;
|
||||
break;
|
||||
|
||||
case B_SECOND:
|
||||
case B_DATE_ELEMENT_SECOND:
|
||||
if (value <= 59)
|
||||
isInRange = true;
|
||||
break;
|
||||
@ -416,15 +416,15 @@ TTimeEdit::_SectionValue(int32 index) const
|
||||
return 0;
|
||||
}
|
||||
switch (fields[index]) {
|
||||
case B_HOUR:
|
||||
case B_DATE_ELEMENT_HOUR:
|
||||
value = fTime.Hour();
|
||||
break;
|
||||
|
||||
case B_MINUTE:
|
||||
case B_DATE_ELEMENT_MINUTE:
|
||||
value = fTime.Minute();
|
||||
break;
|
||||
|
||||
case B_SECOND:
|
||||
case B_DATE_ELEMENT_SECOND:
|
||||
value = fTime.Second();
|
||||
break;
|
||||
|
||||
@ -465,7 +465,7 @@ TDateEdit::KeyDown(const char* bytes, int32 numBytes)
|
||||
return;
|
||||
|
||||
int32 section = FocusIndex();
|
||||
if (section < 1 || section > 2)
|
||||
if (section < 0 || section > 2)
|
||||
return;
|
||||
|
||||
bigtime_t currentTime = system_time();
|
||||
@ -480,12 +480,22 @@ TDateEdit::KeyDown(const char* bytes, int32 numBytes)
|
||||
}
|
||||
|
||||
// if year add 2000
|
||||
if (section == 2) {
|
||||
|
||||
BDateElement* dateFormat;
|
||||
int fieldCount;
|
||||
BCountry* here;
|
||||
be_locale_roster->GetDefaultCountry(&here);
|
||||
here->DateFields(dateFormat, fieldCount, false);
|
||||
|
||||
if (dateFormat[section] == B_DATE_ELEMENT_YEAR) {
|
||||
int32 oldCentury = int32(fHoldValue / 100) * 100;
|
||||
if (number < 10 && oldCentury == 1900)
|
||||
number += 70;
|
||||
number += oldCentury;
|
||||
}
|
||||
|
||||
free(dateFormat);
|
||||
|
||||
// update display value
|
||||
fHoldValue = number;
|
||||
|
||||
@ -509,7 +519,6 @@ TDateEdit::InitView()
|
||||
void
|
||||
TDateEdit::DrawSection(uint32 index, bool hasFocus)
|
||||
{
|
||||
// user defined section drawing
|
||||
TSection *section = NULL;
|
||||
section = static_cast<TSection*> (fSectionList->ItemAt(index));
|
||||
|
||||
@ -517,29 +526,42 @@ TDateEdit::DrawSection(uint32 index, bool hasFocus)
|
||||
return;
|
||||
|
||||
BRect bounds = section->Frame();
|
||||
uint32 value = _SectionValue(index);
|
||||
BDateTime dateTime(fDate, BTime());
|
||||
|
||||
SetLowColor(ViewColor());
|
||||
if (hasFocus) {
|
||||
BString field;
|
||||
if (hasFocus)
|
||||
SetLowColor(tint_color(ViewColor(), B_DARKEN_1_TINT));
|
||||
value = fHoldValue;
|
||||
}
|
||||
|
||||
BString text;
|
||||
if (index != 0) {
|
||||
if (value < 10) text << "0";
|
||||
text << value;
|
||||
} else
|
||||
text.SetTo(fDate.LongMonthName(value));
|
||||
int* fieldPositions;
|
||||
int fieldCount;
|
||||
|
||||
BCountry* country;
|
||||
be_locale_roster->GetDefaultCountry(&country);
|
||||
country->FormatDate(&text, fieldPositions, fieldCount, dateTime.Time_t(),
|
||||
false);
|
||||
// TODO : this should be cached somehow to not redo it for each field
|
||||
|
||||
if (index * 2 + 1 > fieldCount) {
|
||||
free(fieldPositions);
|
||||
return;
|
||||
}
|
||||
|
||||
text.CopyCharsInto(field, fieldPositions[index * 2],
|
||||
fieldPositions[index * 2 + 1] - fieldPositions[index * 2]);
|
||||
|
||||
free(fieldPositions);
|
||||
|
||||
|
||||
// calc and center text in section rect
|
||||
float width = StringWidth(text.String());
|
||||
float width = StringWidth(field);
|
||||
BPoint offset(-(bounds.Width() - width) / 2.0 - 1.0,
|
||||
(bounds.Height() / 2.0 - 6.0));
|
||||
|
||||
SetHighColor(0, 0, 0, 255);
|
||||
FillRect(bounds, B_SOLID_LOW);
|
||||
DrawString(text.String(), bounds.LeftBottom() - offset);
|
||||
DrawString(field, bounds.LeftBottom() - offset);
|
||||
}
|
||||
|
||||
|
||||
@ -554,19 +576,43 @@ TDateEdit::DrawSeparator(uint32 index)
|
||||
BRect bounds = section->Frame();
|
||||
|
||||
float sepWidth = SeparatorWidth();
|
||||
float width = be_plain_font->StringWidth("/");
|
||||
|
||||
BPoint offset(-(sepWidth / 2.0 - width / 2.0) -1.0,
|
||||
bounds.Height() / 2.0 -6.0);
|
||||
|
||||
SetHighColor(0, 0, 0, 255);
|
||||
DrawString("/", bounds.RightBottom() - offset);
|
||||
|
||||
BString text;
|
||||
int* fieldPositions;
|
||||
int fieldCount;
|
||||
|
||||
BCountry* country;
|
||||
be_locale_roster->GetDefaultCountry(&country);
|
||||
BDateTime dateTime(fDate, BTime());
|
||||
country->FormatDate(&text, fieldPositions, fieldCount, dateTime.Time_t(),
|
||||
false);
|
||||
// TODO : this should be cached somehow to not redo it for each field
|
||||
|
||||
if (index * 2 + 2 > fieldCount) {
|
||||
free(fieldPositions);
|
||||
return;
|
||||
}
|
||||
|
||||
BString field;
|
||||
text.CopyCharsInto(field, fieldPositions[index * 2 + 1],
|
||||
fieldPositions[index * 2 + 2] - fieldPositions[index * 2 + 1]);
|
||||
|
||||
free(fieldPositions);
|
||||
|
||||
float width = be_plain_font->StringWidth(field);
|
||||
BPoint offset(-((sepWidth - width) / 2.0) -1.0, bounds.Height() / 2.0 -6.0);
|
||||
DrawString(field, bounds.RightBottom() - offset);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TDateEdit::SetSections(BRect area)
|
||||
{
|
||||
// TODO : we have to be more clever here, as the fields can move and have
|
||||
// different sizes dependin on the locale
|
||||
|
||||
// create sections
|
||||
for (uint32 idx = 0; idx < fSectionCount; idx++)
|
||||
fSectionList->AddItem(new TSection(area));
|
||||
@ -664,15 +710,37 @@ TDateEdit::BuildDispatch(BMessage *message)
|
||||
|
||||
message->AddBool("time", false);
|
||||
|
||||
int32 value;
|
||||
for (int32 index = 0; index < fSectionList->CountItems(); ++index) {
|
||||
value = _SectionValue(index);
|
||||
|
||||
if (index == fFocus)
|
||||
value = fHoldValue;
|
||||
|
||||
message->AddInt32(fields[index], value);
|
||||
BDateElement* dateFormat;
|
||||
int fieldCount;
|
||||
BCountry* here;
|
||||
be_locale_roster->GetDefaultCountry(&here);
|
||||
here->DateFields(dateFormat, fieldCount, false);
|
||||
if (fFocus > fieldCount) {
|
||||
free(dateFormat);
|
||||
return;
|
||||
}
|
||||
for (int32 index = 0; index < fSectionList->CountItems(); ++index) {
|
||||
uint32 data = _SectionValue(index);
|
||||
|
||||
if (fFocus == index)
|
||||
data = fHoldValue;
|
||||
|
||||
switch(dateFormat[index]) {
|
||||
case B_DATE_ELEMENT_MONTH:
|
||||
message->AddInt32(fields[0], data);
|
||||
break;
|
||||
case B_DATE_ELEMENT_DAY:
|
||||
message->AddInt32(fields[1], data);
|
||||
break;
|
||||
case B_DATE_ELEMENT_YEAR:
|
||||
message->AddInt32(fields[2], data);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(dateFormat);
|
||||
}
|
||||
|
||||
|
||||
@ -680,10 +748,18 @@ void
|
||||
TDateEdit::_CheckRange()
|
||||
{
|
||||
int32 value = fHoldValue;
|
||||
BDateElement* fields;
|
||||
int fieldCount;
|
||||
BCountry* here;
|
||||
be_locale_roster->GetDefaultCountry(&here);
|
||||
here->DateFields(fields, fieldCount, false);
|
||||
if (fFocus > fieldCount) {
|
||||
free(fields);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (fFocus) {
|
||||
case 0:
|
||||
// month
|
||||
switch (fields[fFocus]) {
|
||||
case B_DATE_ELEMENT_MONTH:
|
||||
if (value > 12)
|
||||
value = 1;
|
||||
else if (value < 1)
|
||||
@ -692,9 +768,8 @@ TDateEdit::_CheckRange()
|
||||
fDate.SetDate(fDate.Year(), value, fDate.Day());
|
||||
break;
|
||||
|
||||
case 1:
|
||||
case B_DATE_ELEMENT_DAY:
|
||||
{
|
||||
// day
|
||||
int32 days = fDate.DaysInMonth();
|
||||
if (value > days)
|
||||
value = 1;
|
||||
@ -705,8 +780,8 @@ TDateEdit::_CheckRange()
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
// year
|
||||
case B_DATE_ELEMENT_YEAR:
|
||||
// 2037 is the end of 32-bit UNIX time
|
||||
if (value > 2037)
|
||||
value = 2037;
|
||||
else if (value < 1970)
|
||||
@ -716,9 +791,11 @@ TDateEdit::_CheckRange()
|
||||
break;
|
||||
|
||||
default:
|
||||
free(fields);
|
||||
return;
|
||||
}
|
||||
|
||||
free(fields);
|
||||
fHoldValue = value;
|
||||
Draw(Bounds());
|
||||
}
|
||||
@ -728,20 +805,27 @@ bool
|
||||
TDateEdit::_IsValidDoubleDigi(int32 value)
|
||||
{
|
||||
bool isInRange = false;
|
||||
BDateElement* fields;
|
||||
int fieldCount;
|
||||
BCountry* here;
|
||||
be_locale_roster->GetDefaultCountry(&here);
|
||||
here->DateFields(fields, fieldCount, false);
|
||||
if (fFocus > fieldCount) {
|
||||
free(fields);
|
||||
return false;
|
||||
}
|
||||
int32 year = 0;
|
||||
switch (fFocus) {
|
||||
case 1:
|
||||
switch (fields[fFocus]) {
|
||||
case B_DATE_ELEMENT_DAY:
|
||||
{
|
||||
// day
|
||||
int32 days = fDate.DaysInMonth();
|
||||
if (value <= days)
|
||||
isInRange = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
case B_DATE_ELEMENT_YEAR:
|
||||
{
|
||||
// year
|
||||
year = int32(fHoldValue / 100) * 100 + value;
|
||||
if (year <= 2037 && year >= 1970)
|
||||
isInRange = true;
|
||||
@ -749,9 +833,11 @@ TDateEdit::_IsValidDoubleDigi(int32 value)
|
||||
}
|
||||
|
||||
default:
|
||||
free(fields);
|
||||
return isInRange;
|
||||
}
|
||||
|
||||
free(fields);
|
||||
return isInRange;
|
||||
}
|
||||
|
||||
@ -760,12 +846,21 @@ int32
|
||||
TDateEdit::_SectionValue(int32 index) const
|
||||
{
|
||||
int32 value = 0;
|
||||
switch (index) {
|
||||
case 0:
|
||||
BDateElement* fields;
|
||||
int fieldCount;
|
||||
BCountry* here;
|
||||
be_locale_roster->GetDefaultCountry(&here);
|
||||
here->DateFields(fields, fieldCount, false);
|
||||
if (index > fieldCount) {
|
||||
free(fields);
|
||||
return 0;
|
||||
}
|
||||
switch (fields[index]) {
|
||||
case B_DATE_ELEMENT_MONTH:
|
||||
value = fDate.Month();
|
||||
break;
|
||||
|
||||
case 1:
|
||||
case B_DATE_ELEMENT_DAY:
|
||||
value = fDate.Day();
|
||||
break;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user