Author: zooey Date: 2010-08-25 19:34:54 +0200 (Wed, 25 Aug 2010) New Revision: 38357 Changeset: http://dev.haiku-os.org/changeset/38357 Modified: haiku/trunk/src/preferences/time/TimeWindow.cpp haiku/trunk/src/preferences/time/ZoneView.cpp haiku/trunk/src/preferences/time/ZoneView.h Log: 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. Modified: haiku/trunk/src/preferences/time/TimeWindow.cpp =================================================================== --- haiku/trunk/src/preferences/time/TimeWindow.cpp 2010-08-25 15:54:35 UTC (rev 38356) +++ haiku/trunk/src/preferences/time/TimeWindow.cpp 2010-08-25 17:34:54 UTC (rev 38357) @@ -69,6 +69,7 @@ case kRTCUpdate: fDateTimeView->MessageReceived(message); + fTimeZoneView->MessageReceived(message); SetRevertStatus(); break; Modified: haiku/trunk/src/preferences/time/ZoneView.cpp =================================================================== --- haiku/trunk/src/preferences/time/ZoneView.cpp 2010-08-25 15:54:35 UTC (rev 38356) +++ haiku/trunk/src/preferences/time/ZoneView.cpp 2010-08-25 17:34:54 UTC (rev 38357) @@ -57,6 +57,12 @@ 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 @@ void TimeZoneView::AttachedToWindow() { + BView::AttachedToWindow(); if (Parent()) SetViewColor(Parent()->ViewColor()); +} + +void +TimeZoneView::AllAttached() +{ + BView::AllAttached(); if (!fInitialized) { fInitialized = true; @@ -103,18 +116,10 @@ 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 @@ break; } + case H_CITY_CHANGED: + _UpdatePreview(); + break; + case H_SET_TIME_ZONE: { _SetSystemTimeZone(); @@ -151,7 +160,8 @@ _Revert(); break; - case H_CITY_CHANGED: + case kRTCUpdate: + _UpdateCurrent(); _UpdatePreview(); break; @@ -172,7 +182,8 @@ 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 @@ 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 @@ 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 @@ 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 @@ ZoneItemMap::iterator zoneIter; for (zoneIter = zoneMap.begin(); zoneIter != zoneMap.end(); ++zoneIter) fZoneList->AddItem(zoneIter->second); - - fZoneList->Select(fZoneList->IndexOf(fCurrentZoneItem)); } @@ -390,7 +406,7 @@ return; } - BString timeString = _FormatTime(item); + BString timeString = _FormatTime(item->TimeZone()); fPreview->SetText(item->Text()); fPreview->SetTime(timeString.String()); @@ -404,7 +420,7 @@ if (fCurrentZoneItem == NULL) return; - BString timeString = _FormatTime(fCurrentZoneItem); + BString timeString = _FormatTime(fCurrentZoneItem->TimeZone()); fCurrent->SetText(fCurrentZoneItem->Text()); fCurrent->SetTime(timeString.String()); } @@ -416,16 +432,20 @@ /* 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); _kern_set_timezone(timeZone.OffsetFromGMT(), timeZone.ID().String(), @@ -438,22 +458,24 @@ 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; } Modified: haiku/trunk/src/preferences/time/ZoneView.h =================================================================== --- haiku/trunk/src/preferences/time/ZoneView.h 2010-08-25 15:54:35 UTC (rev 38356) +++ haiku/trunk/src/preferences/time/ZoneView.h 2010-08-25 17:34:54 UTC (rev 38357) @@ -14,13 +14,14 @@ #include <View.h> +class BButton; class BMessage; +class BOutlineListView; class BPopUpMenu; -class BOutlineListView; -class BButton; class BTextToolTip; +class BTimeZone; +class TimeZoneListItem; class TTZDisplay; -class TimeZoneListItem; class TimeZoneView : public BView { @@ -29,6 +30,7 @@ virtual ~TimeZoneView(); virtual void AttachedToWindow(); + virtual void AllAttached(); virtual void MessageReceived(BMessage* message); bool CheckCanRevert(); @@ -42,7 +44,8 @@ void _UpdatePreview(); void _UpdateCurrent(); - BString _FormatTime(TimeZoneListItem* zoneItem); + BString _FormatTime(const BTimeZone& timeZone, + bool compensateForLocalOffset = true); void _InitView(); void _BuildZoneMenu();