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:
fDateTimeView->MessageReceived(message);
fTimeZoneView->MessageReceived(message);
SetRevertStatus();
break;
+56 -34
View File
@@ -57,6 +57,12 @@ using BPrivate::ObjectDeleter;
struct TimeZoneItemLess {
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;
}
private:
@@ -93,9 +99,16 @@ TimeZoneView::~TimeZoneView()
void
TimeZoneView::AttachedToWindow()
{
BView::AttachedToWindow();
if (Parent())
SetViewColor(Parent()->ViewColor());
}
void
TimeZoneView::AllAttached()
{
BView::AllAttached();
if (!fInitialized) {
fInitialized = true;
@@ -103,18 +116,10 @@ TimeZoneView::AttachedToWindow()
fZoneList->SetTarget(this);
// update displays
int32 czone = 0;
if (fCurrentZoneItem != NULL) {
czone = fZoneList->IndexOf(fCurrentZoneItem);
} else {
// TODO : else, select ??!
fCurrentZoneItem = (TimeZoneListItem*)fZoneList->ItemAt(0);
fZoneList->Select(fZoneList->IndexOf(fCurrentZoneItem));
fCurrent->SetText(fCurrentZoneItem->Text());
}
fZoneList->Select(czone);
fZoneList->ScrollToSelection();
fCurrent->SetText(fCurrentZoneItem->Text());
}
fZoneList->ScrollToSelection();
}
@@ -140,6 +145,10 @@ TimeZoneView::MessageReceived(BMessage* message)
break;
}
case H_CITY_CHANGED:
_UpdatePreview();
break;
case H_SET_TIME_ZONE:
{
_SetSystemTimeZone();
@@ -151,7 +160,8 @@ TimeZoneView::MessageReceived(BMessage* message)
_Revert();
break;
case H_CITY_CHANGED:
case kRTCUpdate:
_UpdateCurrent();
_UpdatePreview();
break;
@@ -172,7 +182,8 @@ TimeZoneView::GetToolTipAt(BPoint point, BToolTip** _tip)
BString toolTip = item->Text();
toolTip << '\n' << item->TimeZone().ShortName() << " / "
<< item->TimeZone().ShortDaylightSavingName();
<< item->TimeZone().ShortDaylightSavingName()
<< "\nNow: " << _FormatTime(item->TimeZone(), false).String();
delete fToolTip;
fToolTip = new (std::nothrow) BTextToolTip(toolTip.String());
@@ -252,23 +263,27 @@ TimeZoneView::_InitView()
void
TimeZoneView::_BuildZoneMenu()
{
BTimeZone defaultTimeZone = NULL;
BTimeZone defaultTimeZone;
be_locale_roster->GetDefaultTimeZone(&defaultTimeZone);
// Get a list of countries and, for each country, get all the timezones and
// AddUnder() them (only if there are multiple ones).
// Finally expand the current country and highlight the active TZ.
BLanguage defaultLanguage;
be_locale_roster->GetDefaultLanguage(&defaultLanguage);
/*
* 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;
be_locale_roster->GetAvailableTimeZones(&zoneList);
typedef std::map<BString, TimeZoneListItem*, TimeZoneItemLess> ZoneItemMap;
ZoneItemMap zoneMap;
const char* supportedRegions[] = {
const char* kOtherRegion = "<Other>";
const char* kSupportedRegions[] = {
"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;
BString zoneID;
@@ -282,6 +297,9 @@ TimeZoneView::_BuildZoneMenu()
BString region(zoneID, slashPos);
if (region == "Etc")
region = kOtherRegion;
// just accept timezones from "known" regions, as all others are aliases
ZoneItemMap::iterator regionIter = zoneMap.find(region);
if (regionIter == zoneMap.end())
@@ -295,7 +313,7 @@ TimeZoneView::_BuildZoneMenu()
zoneMap[region] = regionItem;
}
BTimeZone* timeZone = new BTimeZone(zoneID);
BTimeZone* timeZone = new BTimeZone(zoneID, &defaultLanguage);
BString tzName = timeZone->Name();
if (tzName == "GMT+00:00")
tzName = "GMT";
@@ -352,8 +370,6 @@ TimeZoneView::_BuildZoneMenu()
ZoneItemMap::iterator zoneIter;
for (zoneIter = zoneMap.begin(); zoneIter != zoneMap.end(); ++zoneIter)
fZoneList->AddItem(zoneIter->second);
fZoneList->Select(fZoneList->IndexOf(fCurrentZoneItem));
}
@@ -390,7 +406,7 @@ TimeZoneView::_UpdatePreview()
return;
}
BString timeString = _FormatTime(item);
BString timeString = _FormatTime(item->TimeZone());
fPreview->SetText(item->Text());
fPreview->SetTime(timeString.String());
@@ -404,7 +420,7 @@ TimeZoneView::_UpdateCurrent()
if (fCurrentZoneItem == NULL)
return;
BString timeString = _FormatTime(fCurrentZoneItem);
BString timeString = _FormatTime(fCurrentZoneItem->TimeZone());
fCurrent->SetText(fCurrentZoneItem->Text());
fCurrent->SetTime(timeString.String());
}
@@ -416,15 +432,19 @@ TimeZoneView::_SetSystemTimeZone()
/* Set sytem timezone for all different API levels. How to do this?
* 1) tell locale-roster about new default timezone
* 2) tell kernel about new timezone offset
* 3) write new POSIX-timezone-info file
*/
int32 selection = fZoneList->CurrentSelection();
if (selection < 0)
return;
fCurrentZoneItem = (TimeZoneListItem*)(fZoneList->ItemAt(selection));
const BTimeZone& timeZone = fCurrentZoneItem->TimeZone();
TimeZoneListItem* item
= static_cast<TimeZoneListItem*>(fZoneList->ItemAt(selection));
if (item == NULL || !item->HasTimeZone())
return;
fCurrentZoneItem = item;
const BTimeZone& timeZone = item->TimeZone();
gMutableLocaleRoster->SetDefaultTimeZone(timeZone);
@@ -438,22 +458,24 @@ TimeZoneView::_SetSystemTimeZone()
BString
TimeZoneView::_FormatTime(TimeZoneListItem* zoneItem)
TimeZoneView::_FormatTime(const BTimeZone& timeZone,
bool compensateForLocalOffset)
{
BString result;
if (zoneItem == NULL)
return result;
BLocale locale;
be_locale_roster->GetDefaultLocale(&locale);
time_t now = time(NULL);
bool rtcIsGMT;
_kern_get_real_time_clock_is_gmt(&rtcIsGMT);
if (!rtcIsGMT) {
now -= zoneItem->OffsetFromGMT() - fCurrentZoneItem->OffsetFromGMT();
if (!rtcIsGMT && compensateForLocalOffset) {
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;
}
+8 -5
View File
@@ -14,13 +14,14 @@
#include <View.h>
class BMessage;
class BPopUpMenu;
class BOutlineListView;
class BButton;
class BMessage;
class BOutlineListView;
class BPopUpMenu;
class BTextToolTip;
class TTZDisplay;
class BTimeZone;
class TimeZoneListItem;
class TTZDisplay;
class TimeZoneView : public BView {
@@ -29,6 +30,7 @@ public:
virtual ~TimeZoneView();
virtual void AttachedToWindow();
virtual void AllAttached();
virtual void MessageReceived(BMessage* message);
bool CheckCanRevert();
@@ -42,7 +44,8 @@ private:
void _UpdatePreview();
void _UpdateCurrent();
BString _FormatTime(TimeZoneListItem* zoneItem);
BString _FormatTime(const BTimeZone& timeZone,
bool compensateForLocalOffset = true);
void _InitView();
void _BuildZoneMenu();