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:
Oliver Tappe
2010-08-25 17:34:54 +00:00
parent 4c6e53f601
commit 447b7fded1
3 changed files with 65 additions and 39 deletions
+1
View File
@@ -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;
+56 -34
View File
@@ -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;
} }
+8 -5
View File
@@ -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();