More work on Time preflet
* update the times shown on timezone page when the user switches RTC between GMT/Local Time * rename "Etc"-region to "<Other>" and sort it at the end of the list * add current time of the corresponding zone to tooltip of a timezone-listitem * show timezone names in the default language - not the default locale, as the latter is just responsible for date/time and numeric formats This works, but the localized names are sometimes a bit strange (for instance in English, whose timezone names have a superfluous ' Time' prefix). I am going to experiment with mixing country information back into the game, next. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38357 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -69,6 +69,7 @@ TTimeWindow::MessageReceived(BMessage* message)
|
|||||||
|
|
||||||
case kRTCUpdate:
|
case kRTCUpdate:
|
||||||
fDateTimeView->MessageReceived(message);
|
fDateTimeView->MessageReceived(message);
|
||||||
|
fTimeZoneView->MessageReceived(message);
|
||||||
SetRevertStatus();
|
SetRevertStatus();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -57,6 +57,12 @@ using BPrivate::ObjectDeleter;
|
|||||||
struct TimeZoneItemLess {
|
struct TimeZoneItemLess {
|
||||||
bool operator()(const BString& first, const BString& second)
|
bool operator()(const BString& first, const BString& second)
|
||||||
{
|
{
|
||||||
|
// sort anything starting with '<' behind anything else
|
||||||
|
if (first.ByteAt(0) == '<') {
|
||||||
|
if (second.ByteAt(0) != '<')
|
||||||
|
return false;
|
||||||
|
} else if (second.ByteAt(0) == '<')
|
||||||
|
return true;
|
||||||
return fCollator.Compare(first.String(), second.String()) < 0;
|
return fCollator.Compare(first.String(), second.String()) < 0;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
@@ -93,9 +99,16 @@ TimeZoneView::~TimeZoneView()
|
|||||||
void
|
void
|
||||||
TimeZoneView::AttachedToWindow()
|
TimeZoneView::AttachedToWindow()
|
||||||
{
|
{
|
||||||
|
BView::AttachedToWindow();
|
||||||
if (Parent())
|
if (Parent())
|
||||||
SetViewColor(Parent()->ViewColor());
|
SetViewColor(Parent()->ViewColor());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TimeZoneView::AllAttached()
|
||||||
|
{
|
||||||
|
BView::AllAttached();
|
||||||
if (!fInitialized) {
|
if (!fInitialized) {
|
||||||
fInitialized = true;
|
fInitialized = true;
|
||||||
|
|
||||||
@@ -103,18 +116,10 @@ TimeZoneView::AttachedToWindow()
|
|||||||
fZoneList->SetTarget(this);
|
fZoneList->SetTarget(this);
|
||||||
|
|
||||||
// update displays
|
// update displays
|
||||||
int32 czone = 0;
|
|
||||||
if (fCurrentZoneItem != NULL) {
|
if (fCurrentZoneItem != NULL) {
|
||||||
czone = fZoneList->IndexOf(fCurrentZoneItem);
|
fZoneList->Select(fZoneList->IndexOf(fCurrentZoneItem));
|
||||||
} else {
|
fCurrent->SetText(fCurrentZoneItem->Text());
|
||||||
// TODO : else, select ??!
|
|
||||||
fCurrentZoneItem = (TimeZoneListItem*)fZoneList->ItemAt(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fZoneList->Select(czone);
|
|
||||||
|
|
||||||
fZoneList->ScrollToSelection();
|
|
||||||
fCurrent->SetText(fCurrentZoneItem->Text());
|
|
||||||
}
|
}
|
||||||
fZoneList->ScrollToSelection();
|
fZoneList->ScrollToSelection();
|
||||||
}
|
}
|
||||||
@@ -140,6 +145,10 @@ TimeZoneView::MessageReceived(BMessage* message)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case H_CITY_CHANGED:
|
||||||
|
_UpdatePreview();
|
||||||
|
break;
|
||||||
|
|
||||||
case H_SET_TIME_ZONE:
|
case H_SET_TIME_ZONE:
|
||||||
{
|
{
|
||||||
_SetSystemTimeZone();
|
_SetSystemTimeZone();
|
||||||
@@ -151,7 +160,8 @@ TimeZoneView::MessageReceived(BMessage* message)
|
|||||||
_Revert();
|
_Revert();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case H_CITY_CHANGED:
|
case kRTCUpdate:
|
||||||
|
_UpdateCurrent();
|
||||||
_UpdatePreview();
|
_UpdatePreview();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -172,7 +182,8 @@ TimeZoneView::GetToolTipAt(BPoint point, BToolTip** _tip)
|
|||||||
|
|
||||||
BString toolTip = item->Text();
|
BString toolTip = item->Text();
|
||||||
toolTip << '\n' << item->TimeZone().ShortName() << " / "
|
toolTip << '\n' << item->TimeZone().ShortName() << " / "
|
||||||
<< item->TimeZone().ShortDaylightSavingName();
|
<< item->TimeZone().ShortDaylightSavingName()
|
||||||
|
<< "\nNow: " << _FormatTime(item->TimeZone(), false).String();
|
||||||
|
|
||||||
delete fToolTip;
|
delete fToolTip;
|
||||||
fToolTip = new (std::nothrow) BTextToolTip(toolTip.String());
|
fToolTip = new (std::nothrow) BTextToolTip(toolTip.String());
|
||||||
@@ -252,23 +263,27 @@ TimeZoneView::_InitView()
|
|||||||
void
|
void
|
||||||
TimeZoneView::_BuildZoneMenu()
|
TimeZoneView::_BuildZoneMenu()
|
||||||
{
|
{
|
||||||
BTimeZone defaultTimeZone = NULL;
|
BTimeZone defaultTimeZone;
|
||||||
be_locale_roster->GetDefaultTimeZone(&defaultTimeZone);
|
be_locale_roster->GetDefaultTimeZone(&defaultTimeZone);
|
||||||
|
|
||||||
// Get a list of countries and, for each country, get all the timezones and
|
BLanguage defaultLanguage;
|
||||||
// AddUnder() them (only if there are multiple ones).
|
be_locale_roster->GetDefaultLanguage(&defaultLanguage);
|
||||||
// Finally expand the current country and highlight the active TZ.
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Group timezones by regions, but filter out unwanted (duplicate) regions
|
||||||
|
* and add an additional region with generic GMT-offset timezones at the end
|
||||||
|
*/
|
||||||
BMessage zoneList;
|
BMessage zoneList;
|
||||||
be_locale_roster->GetAvailableTimeZones(&zoneList);
|
be_locale_roster->GetAvailableTimeZones(&zoneList);
|
||||||
|
|
||||||
typedef std::map<BString, TimeZoneListItem*, TimeZoneItemLess> ZoneItemMap;
|
typedef std::map<BString, TimeZoneListItem*, TimeZoneItemLess> ZoneItemMap;
|
||||||
ZoneItemMap zoneMap;
|
ZoneItemMap zoneMap;
|
||||||
const char* supportedRegions[] = {
|
const char* kOtherRegion = "<Other>";
|
||||||
|
const char* kSupportedRegions[] = {
|
||||||
"Africa", "America", "Antarctica", "Arctic", "Asia", "Atlantic",
|
"Africa", "America", "Antarctica", "Arctic", "Asia", "Atlantic",
|
||||||
"Australia", "Etc", "Europe", "Indian", "Pacific", NULL
|
"Australia", "Europe", "Indian", "Pacific", kOtherRegion, NULL
|
||||||
};
|
};
|
||||||
for (const char** region = supportedRegions; *region != NULL; ++region)
|
for (const char** region = kSupportedRegions; *region != NULL; ++region)
|
||||||
zoneMap[*region] = NULL;
|
zoneMap[*region] = NULL;
|
||||||
|
|
||||||
BString zoneID;
|
BString zoneID;
|
||||||
@@ -282,6 +297,9 @@ TimeZoneView::_BuildZoneMenu()
|
|||||||
|
|
||||||
BString region(zoneID, slashPos);
|
BString region(zoneID, slashPos);
|
||||||
|
|
||||||
|
if (region == "Etc")
|
||||||
|
region = kOtherRegion;
|
||||||
|
|
||||||
// just accept timezones from "known" regions, as all others are aliases
|
// just accept timezones from "known" regions, as all others are aliases
|
||||||
ZoneItemMap::iterator regionIter = zoneMap.find(region);
|
ZoneItemMap::iterator regionIter = zoneMap.find(region);
|
||||||
if (regionIter == zoneMap.end())
|
if (regionIter == zoneMap.end())
|
||||||
@@ -295,7 +313,7 @@ TimeZoneView::_BuildZoneMenu()
|
|||||||
zoneMap[region] = regionItem;
|
zoneMap[region] = regionItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
BTimeZone* timeZone = new BTimeZone(zoneID);
|
BTimeZone* timeZone = new BTimeZone(zoneID, &defaultLanguage);
|
||||||
BString tzName = timeZone->Name();
|
BString tzName = timeZone->Name();
|
||||||
if (tzName == "GMT+00:00")
|
if (tzName == "GMT+00:00")
|
||||||
tzName = "GMT";
|
tzName = "GMT";
|
||||||
@@ -352,8 +370,6 @@ TimeZoneView::_BuildZoneMenu()
|
|||||||
ZoneItemMap::iterator zoneIter;
|
ZoneItemMap::iterator zoneIter;
|
||||||
for (zoneIter = zoneMap.begin(); zoneIter != zoneMap.end(); ++zoneIter)
|
for (zoneIter = zoneMap.begin(); zoneIter != zoneMap.end(); ++zoneIter)
|
||||||
fZoneList->AddItem(zoneIter->second);
|
fZoneList->AddItem(zoneIter->second);
|
||||||
|
|
||||||
fZoneList->Select(fZoneList->IndexOf(fCurrentZoneItem));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -390,7 +406,7 @@ TimeZoneView::_UpdatePreview()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BString timeString = _FormatTime(item);
|
BString timeString = _FormatTime(item->TimeZone());
|
||||||
fPreview->SetText(item->Text());
|
fPreview->SetText(item->Text());
|
||||||
fPreview->SetTime(timeString.String());
|
fPreview->SetTime(timeString.String());
|
||||||
|
|
||||||
@@ -404,7 +420,7 @@ TimeZoneView::_UpdateCurrent()
|
|||||||
if (fCurrentZoneItem == NULL)
|
if (fCurrentZoneItem == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
BString timeString = _FormatTime(fCurrentZoneItem);
|
BString timeString = _FormatTime(fCurrentZoneItem->TimeZone());
|
||||||
fCurrent->SetText(fCurrentZoneItem->Text());
|
fCurrent->SetText(fCurrentZoneItem->Text());
|
||||||
fCurrent->SetTime(timeString.String());
|
fCurrent->SetTime(timeString.String());
|
||||||
}
|
}
|
||||||
@@ -416,15 +432,19 @@ TimeZoneView::_SetSystemTimeZone()
|
|||||||
/* Set sytem timezone for all different API levels. How to do this?
|
/* Set sytem timezone for all different API levels. How to do this?
|
||||||
* 1) tell locale-roster about new default timezone
|
* 1) tell locale-roster about new default timezone
|
||||||
* 2) tell kernel about new timezone offset
|
* 2) tell kernel about new timezone offset
|
||||||
* 3) write new POSIX-timezone-info file
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int32 selection = fZoneList->CurrentSelection();
|
int32 selection = fZoneList->CurrentSelection();
|
||||||
if (selection < 0)
|
if (selection < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fCurrentZoneItem = (TimeZoneListItem*)(fZoneList->ItemAt(selection));
|
TimeZoneListItem* item
|
||||||
const BTimeZone& timeZone = fCurrentZoneItem->TimeZone();
|
= static_cast<TimeZoneListItem*>(fZoneList->ItemAt(selection));
|
||||||
|
if (item == NULL || !item->HasTimeZone())
|
||||||
|
return;
|
||||||
|
|
||||||
|
fCurrentZoneItem = item;
|
||||||
|
const BTimeZone& timeZone = item->TimeZone();
|
||||||
|
|
||||||
gMutableLocaleRoster->SetDefaultTimeZone(timeZone);
|
gMutableLocaleRoster->SetDefaultTimeZone(timeZone);
|
||||||
|
|
||||||
@@ -438,22 +458,24 @@ TimeZoneView::_SetSystemTimeZone()
|
|||||||
|
|
||||||
|
|
||||||
BString
|
BString
|
||||||
TimeZoneView::_FormatTime(TimeZoneListItem* zoneItem)
|
TimeZoneView::_FormatTime(const BTimeZone& timeZone,
|
||||||
|
bool compensateForLocalOffset)
|
||||||
{
|
{
|
||||||
BString result;
|
BString result;
|
||||||
|
|
||||||
if (zoneItem == NULL)
|
|
||||||
return result;
|
|
||||||
|
|
||||||
BLocale locale;
|
BLocale locale;
|
||||||
be_locale_roster->GetDefaultLocale(&locale);
|
be_locale_roster->GetDefaultLocale(&locale);
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
bool rtcIsGMT;
|
bool rtcIsGMT;
|
||||||
_kern_get_real_time_clock_is_gmt(&rtcIsGMT);
|
_kern_get_real_time_clock_is_gmt(&rtcIsGMT);
|
||||||
if (!rtcIsGMT) {
|
if (!rtcIsGMT && compensateForLocalOffset) {
|
||||||
now -= zoneItem->OffsetFromGMT() - fCurrentZoneItem->OffsetFromGMT();
|
int32 currentOffset
|
||||||
|
= fCurrentZoneItem != NULL && fCurrentZoneItem->HasTimeZone()
|
||||||
|
? fCurrentZoneItem->OffsetFromGMT()
|
||||||
|
: 0;
|
||||||
|
now -= timeZone.OffsetFromGMT() - currentOffset;
|
||||||
}
|
}
|
||||||
locale.FormatTime(&result, now, false, &zoneItem->TimeZone());
|
locale.FormatTime(&result, now, false, &timeZone);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,13 +14,14 @@
|
|||||||
#include <View.h>
|
#include <View.h>
|
||||||
|
|
||||||
|
|
||||||
class BMessage;
|
|
||||||
class BPopUpMenu;
|
|
||||||
class BOutlineListView;
|
|
||||||
class BButton;
|
class BButton;
|
||||||
|
class BMessage;
|
||||||
|
class BOutlineListView;
|
||||||
|
class BPopUpMenu;
|
||||||
class BTextToolTip;
|
class BTextToolTip;
|
||||||
class TTZDisplay;
|
class BTimeZone;
|
||||||
class TimeZoneListItem;
|
class TimeZoneListItem;
|
||||||
|
class TTZDisplay;
|
||||||
|
|
||||||
|
|
||||||
class TimeZoneView : public BView {
|
class TimeZoneView : public BView {
|
||||||
@@ -29,6 +30,7 @@ public:
|
|||||||
virtual ~TimeZoneView();
|
virtual ~TimeZoneView();
|
||||||
|
|
||||||
virtual void AttachedToWindow();
|
virtual void AttachedToWindow();
|
||||||
|
virtual void AllAttached();
|
||||||
virtual void MessageReceived(BMessage* message);
|
virtual void MessageReceived(BMessage* message);
|
||||||
bool CheckCanRevert();
|
bool CheckCanRevert();
|
||||||
|
|
||||||
@@ -42,7 +44,8 @@ private:
|
|||||||
|
|
||||||
void _UpdatePreview();
|
void _UpdatePreview();
|
||||||
void _UpdateCurrent();
|
void _UpdateCurrent();
|
||||||
BString _FormatTime(TimeZoneListItem* zoneItem);
|
BString _FormatTime(const BTimeZone& timeZone,
|
||||||
|
bool compensateForLocalOffset = true);
|
||||||
|
|
||||||
void _InitView();
|
void _InitView();
|
||||||
void _BuildZoneMenu();
|
void _BuildZoneMenu();
|
||||||
|
|||||||
Reference in New Issue
Block a user