Author: zooey Date: 2010-07-29 22:10:26 +0200 (Thu, 29 Jul 2010) New Revision: 37813 Changeset: http://dev.haiku-os.org/changeset/37813 Added: haiku/trunk/headers/os/locale/TimeZone.h haiku/trunk/src/kits/locale/TimeZone.cpp Removed: haiku/trunk/headers/os/locale/TimeZone.h haiku/trunk/src/kits/locale/TimeZone.cpp Modified: haiku/trunk/src/kits/locale/Country.cpp haiku/trunk/src/kits/locale/LocaleRoster.cpp haiku/trunk/src/preferences/time/Jamfile haiku/trunk/src/preferences/time/TZDisplay.cpp haiku/trunk/src/preferences/time/TimeZoneListItem.cpp haiku/trunk/src/preferences/time/TimeZoneListItem.h haiku/trunk/src/preferences/time/ZoneView.cpp Log: Improved the Time preflet (still not working properly, though) * basically rewrote TimeZone to sport a nicer to use interface * adjusted all users of TimeZone accordingly * changed TZDisplay to show the Date next to the label, in order to avoid that long timezone names draw all over it * the timezone listview is now properly sorted according to the current language (using BCollator) * fixed a couple of bugs (overflows, etc.) that caused incorrect GMT offsets to be used during computations Added: haiku/trunk/headers/os/locale/TimeZone.h =================================================================== --- haiku/trunk/headers/os/locale/TimeZone.h (rev 0) +++ haiku/trunk/headers/os/locale/TimeZone.h 2010-07-29 20:10:26 UTC (rev 37813) @@ -0,0 +1,34 @@ +/* + * Copyright 2010, Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + */ +#ifndef _TIME_ZONE_H +#define _TIME_ZONE_H + + +#include <String.h> + + +class BTimeZone { +public: + BTimeZone(const char* zoneCode = NULL); + ~BTimeZone(); + + const BString& Code() const; + const BString& Name() const; + int OffsetFromGMT() const; + + status_t InitCheck() const; + +private: + void _Init(const char* zoneCode); + + BString fCode; + BString fName; + int fOffsetFromGMT; + + status_t fInitStatus; +}; + + +#endif // _TIME_ZONE_H Modified: haiku/trunk/src/kits/locale/Country.cpp =================================================================== --- haiku/trunk/src/kits/locale/Country.cpp 2010-07-29 20:03:05 UTC (rev 37812) +++ haiku/trunk/src/kits/locale/Country.cpp 2010-07-29 20:10:26 UTC (rev 37813) @@ -1065,10 +1065,8 @@ // remaining zones after that while ((tzName = icuTimeZoneList->next(NULL, error)) != NULL) { if (error == U_ZERO_ERROR) { - BString readableName; BTimeZone* timeZone = new BTimeZone(tzName); - timeZone->GetName(readableName); - timeZoneMap.insert(std::pair<BString, BTimeZone*>(readableName, + timeZoneMap.insert(std::pair<BString, BTimeZone*>(timeZone->Name(), timeZone)); } else error = U_ZERO_ERROR; Modified: haiku/trunk/src/kits/locale/LocaleRoster.cpp =================================================================== --- haiku/trunk/src/kits/locale/LocaleRoster.cpp 2010-07-29 20:03:05 UTC (rev 37812) +++ haiku/trunk/src/kits/locale/LocaleRoster.cpp 2010-07-29 20:10:26 UTC (rev 37813) @@ -511,7 +511,7 @@ if (!timezone) return B_BAD_VALUE; - *timezone = new(std::nothrow) BTimeZone(""); + *timezone = new(std::nothrow) BTimeZone(); return B_OK; } Added: haiku/trunk/src/kits/locale/TimeZone.cpp =================================================================== --- haiku/trunk/src/kits/locale/TimeZone.cpp (rev 0) +++ haiku/trunk/src/kits/locale/TimeZone.cpp 2010-07-29 20:10:26 UTC (rev 37813) @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2010, Haiku, Inc. + * Distributed under the terms of the MIT license. + * + * Authors: + * Adrien Destugues <pulkomandy@xxxxxxxxxxxxxxxxx> + * Oliver Tappe <zooey@xxxxxxxxxxxxxxx> + */ + + +#include <TimeZone.h> + +#include <unicode/timezone.h> +#include <ICUWrapper.h> + + +BTimeZone::BTimeZone(const char* zoneCode) +{ + _Init(zoneCode); +} + + +BTimeZone::~BTimeZone() +{ +} + + +const BString& +BTimeZone::Name() const +{ + return fName; +} + + +const BString& +BTimeZone::Code() const +{ + return fCode; +} + + +int +BTimeZone::OffsetFromGMT() const +{ + return fOffsetFromGMT; +} + + +status_t +BTimeZone::InitCheck() const +{ + return fInitStatus; +} + + +void +BTimeZone::_Init(const char* zoneCode) +{ + TimeZone* icuTimeZone; + if (zoneCode == NULL || zoneCode[0] == '\0') + icuTimeZone = TimeZone::createDefault(); + else + icuTimeZone = TimeZone::createTimeZone(zoneCode); + + UnicodeString unicodeString; + icuTimeZone->getID(unicodeString); + BStringByteSink converter(&fCode); + unicodeString.toUTF8(converter); + + unicodeString.remove(); + icuTimeZone->getDisplayName(unicodeString); + converter.SetTo(&fName); + unicodeString.toUTF8(converter); + + int32_t rawOffset; + int32_t dstOffset; + UDate nowMillis = 1000 * (double)time(NULL); + UErrorCode error = U_ZERO_ERROR; + icuTimeZone->getOffset(nowMillis, FALSE, rawOffset, dstOffset, error); + + if (error != U_ZERO_ERROR) { + fOffsetFromGMT = 0; + fInitStatus = B_ERROR; + } else { + fOffsetFromGMT = (rawOffset + dstOffset) / 1000; + // we want seconds, not ms (which ICU gives us) + fInitStatus = B_OK; + } +} Modified: haiku/trunk/src/preferences/time/Jamfile =================================================================== --- haiku/trunk/src/preferences/time/Jamfile 2010-07-29 20:03:05 UTC (rev 37812) +++ haiku/trunk/src/preferences/time/Jamfile 2010-07-29 20:10:26 UTC (rev 37813) @@ -5,19 +5,19 @@ UsePrivateHeaders shared ; UsePrivateSystemHeaders ; -Preference Time : - AnalogClock.cpp - BaseView.cpp - Bitmaps.cpp - DateTimeEdit.cpp - SectionEdit.cpp - DateTimeView.cpp - Time.cpp - TimeSettings.cpp +Preference Time : + AnalogClock.cpp + BaseView.cpp + Bitmaps.cpp + DateTimeEdit.cpp + SectionEdit.cpp + DateTimeView.cpp + Time.cpp + TimeSettings.cpp TimeWindow.cpp TimeZoneListItem.cpp - TZDisplay.cpp - ZoneView.cpp + TZDisplay.cpp + ZoneView.cpp : be libshared.a $(TARGET_LIBSUPC++) $(HAIKU_LOCALE_LIBS) : Time.rdef ; Modified: haiku/trunk/src/preferences/time/TZDisplay.cpp =================================================================== --- haiku/trunk/src/preferences/time/TZDisplay.cpp 2010-07-29 20:03:05 UTC (rev 37812) +++ haiku/trunk/src/preferences/time/TZDisplay.cpp 2010-07-29 20:10:26 UTC (rev 37813) @@ -71,6 +71,7 @@ pt.y += fontHeight; DrawString(fText.String(), pt); + pt.y -= fontHeight; pt.x = bounds.right - StringWidth(fTime.String()) - 2.0; DrawString(fTime.String(), pt); } Modified: haiku/trunk/src/preferences/time/TimeZoneListItem.cpp =================================================================== --- haiku/trunk/src/preferences/time/TimeZoneListItem.cpp 2010-07-29 20:03:05 UTC (rev 37812) +++ haiku/trunk/src/preferences/time/TimeZoneListItem.cpp 2010-07-29 20:10:26 UTC (rev 37813) @@ -21,6 +21,9 @@ #include <Window.h> +static const BString skDefaultString; + + TimeZoneListItem::TimeZoneListItem(const char* text, BCountry* country, BTimeZone* timeZone) : @@ -92,13 +95,31 @@ } -void -TimeZoneListItem::Code(char* buffer) +const BString& +TimeZoneListItem::Code() const { - if (fTimeZone == NULL) { - buffer[0] = '\0'; - return; - } + if (fTimeZone == NULL) + return skDefaultString; - fTimeZone->GetCode(buffer, 50); + return fTimeZone->Code(); } + + +const BString& +TimeZoneListItem::Name() const +{ + if (fTimeZone == NULL) + return skDefaultString; + + return fTimeZone->Name(); +} + + +int +TimeZoneListItem::OffsetFromGMT() const +{ + if (fTimeZone == NULL) + return 0; + + return fTimeZone->OffsetFromGMT(); +} Modified: haiku/trunk/src/preferences/time/TimeZoneListItem.h =================================================================== --- haiku/trunk/src/preferences/time/TimeZoneListItem.h 2010-07-29 20:03:05 UTC (rev 37812) +++ haiku/trunk/src/preferences/time/TimeZoneListItem.h 2010-07-29 20:10:26 UTC (rev 37813) @@ -26,8 +26,11 @@ void DrawItem(BView* owner, BRect frame, bool complete = false); - void Code(char* buffer); + const BString& Code() const; + const BString& Name() const; + int OffsetFromGMT() const; + private: BBitmap* fIcon; BTimeZone* fTimeZone; Modified: haiku/trunk/src/preferences/time/ZoneView.cpp =================================================================== --- haiku/trunk/src/preferences/time/ZoneView.cpp 2010-07-29 20:03:05 UTC (rev 37812) +++ haiku/trunk/src/preferences/time/ZoneView.cpp 2010-07-29 20:10:26 UTC (rev 37813) @@ -7,6 +7,7 @@ * Julun <host.haiku@xxxxxx> * Philippe Saint-Pierre <stpere@xxxxxxxxx> * Adrien Destugues <pulkomandy@xxxxxxxxxxxxxxxxx> + * Oliver Tappe <zooey@xxxxxxxxxxxxxxx> */ /* @@ -20,6 +21,7 @@ #include <stdlib.h> #include <Button.h> +#include <Collator.h> #include <Directory.h> #include <Entry.h> #include <FindDirectory.h> @@ -42,13 +44,17 @@ #include "TimeWindow.h" +static BCollator sCollator; + // used to sort the timezone list + + TimeZoneView::TimeZoneView(BRect frame) - : BView(frame, "timeZoneView", B_FOLLOW_NONE, B_WILL_DRAW - | B_NAVIGABLE_JUMP), fInitialized(false) + : + BView(frame, "timeZoneView", B_FOLLOW_NONE, B_WILL_DRAW | B_NAVIGABLE_JUMP), + fCurrentZone(NULL), + fOldZone(NULL), + fInitialized(false) { - fCurrentZone = NULL; - fOldZone = NULL; - // TODO : get default timezone from locale kit _InitView(); } @@ -231,11 +237,13 @@ void TimeZoneView::_BuildRegionMenu() { - // Get a list of countries - // For each country, get all the timezones and AddItemUnder them - // (only if there are multiple ones ?) - // Unfold the current country and highlight the selected TZ + BTimeZone* defaultTimeZone = NULL; + 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. + BMessage countryList; be_locale_roster->GetAvailableCountries(&countryList); @@ -249,6 +257,7 @@ // Now list the timezones for this country BList tzList; + BTimeZone* timeZone; TimeZoneListItem* countryItem; switch (country.GetTimeZones(tzList)) { @@ -257,30 +266,47 @@ break; case 1: // Only one Timezone, no need to add it to the list - countryItem = new TimeZoneListItem(fullName, &country, - (BTimeZone*)tzList.ItemAt(0)); + timeZone = (BTimeZone*)tzList.ItemAt(0); + countryItem + = new TimeZoneListItem(fullName, &country, timeZone); fCityList->AddItem(countryItem); + if (timeZone->Code() == defaultTimeZone->Code()) + fCurrentZone = countryItem; break; default: countryItem = new TimeZoneListItem(fullName, &country, NULL); + countryItem->SetExpanded(false); fCityList->AddItem(countryItem); - BTimeZone* timeZone; for (int j = 0; (timeZone = (BTimeZone*)tzList.ItemAt(j)) != NULL; j++) { - BString readableName; - timeZone->GetName(readableName); - BStringItem* tzItem = new TimeZoneListItem(readableName, - NULL, timeZone); + TimeZoneListItem* tzItem = new TimeZoneListItem( + timeZone->Name(), NULL, timeZone); fCityList->AddUnder(tzItem, countryItem); + if (timeZone->Code() == defaultTimeZone->Code()) + { + fCurrentZone = tzItem; + countryItem->SetExpanded(true); + } } break; } } - fCurrentZone = fOldZone = (TimeZoneListItem*)fCityList->ItemAt(0); - // TODO get the actual setting from locale kit + fOldZone = fCurrentZone; + + delete defaultTimeZone; + + struct ListSorter { + static int compare(const BListItem* first, const BListItem* second) + { + return sCollator.Compare(((BStringItem*)first)->Text(), + ((BStringItem*)second)->Text()); + } + }; + fCityList->SortItemsUnder(NULL, true, ListSorter::compare); + } @@ -289,26 +315,18 @@ { int32 selection = fCityList->CurrentSelection(); if (selection >= 0) { - TimeZoneListItem* item = (TimeZoneListItem*)fCityList->ItemAt( - selection); + TimeZoneListItem* item + = (TimeZoneListItem*)fCityList->ItemAt(selection); - // set timezone to selection - char buffer[50]; - item->Code(buffer); - _SetTimeZone(buffer); - // calc preview time - time_t current = time(NULL); + time_t current = time(NULL) + item->OffsetFromGMT(); struct tm localTime; - localtime_r(¤t, &localTime); + gmtime_r(¤t, &localTime); // update prview fPreview->SetText(item->Text()); fPreview->SetTime(localTime.tm_hour, localTime.tm_min); - fCurrentZone->Code(buffer); - _SetTimeZone(buffer); - fSetZone->SetEnabled((strcmp(fCurrent->Text(), item->Text()) != 0)); } } @@ -317,9 +335,7 @@ void TimeZoneView::_SetCurrent(const char* text) { - char buffer[50]; - fCurrentZone->Code(buffer); - _SetTimeZone(buffer); + _SetTimeZone(fCurrentZone->Code().String()); time_t current = time(NULL); struct tm localTime; @@ -345,18 +361,16 @@ if (selection < 0) return; - char timeZoneCode[50]; - ((TimeZoneListItem*)fCityList->ItemAt(selection))->Code(timeZoneCode); + const BString& code + = ((TimeZoneListItem*)fCityList->ItemAt(selection))->Code(); + _SetTimeZone(code.String()); - // update environment - _SetTimeZone(timeZoneCode); - // update display time_t current = time(NULL); struct tm localTime; localtime_r(¤t, &localTime); - set_timezone(timeZoneCode); + set_timezone(code.String()); // disable button fSetZone->SetEnabled(false);