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


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@37813 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Oliver Tappe
2010-07-29 20:10:26 +00:00
parent 96e5a8739a
commit 99d2aa985b
9 changed files with 178 additions and 111 deletions
+23 -20
View File
@@ -1,31 +1,34 @@
/*
Copyright 2010, Haiku, Inc.
Distributed under the terms of the MIT License.
*/
* Copyright 2010, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _TIME_ZONE_H
#define _TIME_ZONE_H
#ifndef __TIMEZONE_H__
#define __TIMEZONE_H__
class BString;
namespace icu_44 {
class TimeZone;
}
#include <String.h>
class BTimeZone {
public:
BTimeZone(const char* zoneCode);
~BTimeZone();
public:
BTimeZone(const char* zoneCode = NULL);
~BTimeZone();
void GetName(BString& name);
void GetCode(char* buffer, int size);
int OffsetFromGMT();
const BString& Code() const;
const BString& Name() const;
int OffsetFromGMT() const;
private:
icu_44::TimeZone* fICUTimeZone;
status_t InitCheck() const;
private:
void _Init(const char* zoneCode);
BString fCode;
BString fName;
int fOffsetFromGMT;
status_t fInitStatus;
};
#endif
#endif // _TIME_ZONE_H
+1 -3
View File
@@ -1065,10 +1065,8 @@ BCountry::GetTimeZones(BList& timezones)
// 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;
+1 -1
View File
@@ -511,7 +511,7 @@ BLocaleRoster::GetDefaultTimeZone(BTimeZone **timezone) const
if (!timezone)
return B_BAD_VALUE;
*timezone = new(std::nothrow) BTimeZone("");
*timezone = new(std::nothrow) BTimeZone();
return B_OK;
}
+56 -29
View File
@@ -1,62 +1,89 @@
/*
Copyright 2010, Adrien Destugues <pulkomandy@pulkomandy.ath.cx>
Distributed under the terms of the MIT License.
*/
* Copyright (c) 2010, Haiku, Inc.
* Distributed under the terms of the MIT license.
*
* Authors:
* Adrien Destugues <pulkomandy@pulkomandy.ath.cx>
* Oliver Tappe <zooey@hirschkaefer.de>
*/
#include <TimeZone.h>
#include <String.h>
#include <unicode/timezone.h>
#include <ICUWrapper.h>
BTimeZone::BTimeZone(const char* zoneCode)
{
fICUTimeZone = TimeZone::createTimeZone(zoneCode);
_Init(zoneCode);
}
BTimeZone::~BTimeZone()
{
delete fICUTimeZone;
}
void
BTimeZone::GetName(BString& name)
const BString&
BTimeZone::Name() const
{
UnicodeString unicodeName;
fICUTimeZone->getDisplayName(unicodeName);
BStringByteSink converter(&name);
unicodeName.toUTF8(converter);
return fName;
}
void
BTimeZone::GetCode(char* buffer, int size)
const BString&
BTimeZone::Code() const
{
UnicodeString unicodeName;
fICUTimeZone->getID(unicodeName);
CheckedArrayByteSink converter(buffer, size);
unicodeName.toUTF8(converter);
return fCode;
}
int
BTimeZone::OffsetFromGMT()
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;
time_t now;
UDate nowMillis = 1000 * (double)time(NULL);
UErrorCode error = U_ZERO_ERROR;
fICUTimeZone->getOffset(time(&now) * 1000, FALSE, rawOffset, dstOffset
, error);
if (error != U_ZERO_ERROR)
return 0;
else
return rawOffset + dstOffset;
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;
}
}
+11 -11
View File
@@ -5,19 +5,19 @@ SetSubDirSupportedPlatformsBeOSCompatible ;
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
;
+1
View File
@@ -71,6 +71,7 @@ TTZDisplay::Draw(BRect /* updateRect */)
pt.y += fontHeight;
DrawString(fText.String(), pt);
pt.y -= fontHeight;
pt.x = bounds.right - StringWidth(fTime.String()) - 2.0;
DrawString(fTime.String(), pt);
}
+28 -7
View File
@@ -21,6 +21,9 @@
#include <Window.h>
static const BString skDefaultString;
TimeZoneListItem::TimeZoneListItem(const char* text, BCountry* country,
BTimeZone* timeZone)
:
@@ -92,13 +95,31 @@ TimeZoneListItem::DrawItem(BView* owner, BRect frame, bool complete)
}
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();
}
+4 -1
View File
@@ -26,7 +26,10 @@ public:
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;
+53 -39
View File
@@ -7,6 +7,7 @@
* Julun <host.haiku@gmx.de>
* Philippe Saint-Pierre <stpere@gmail.com>
* Adrien Destugues <pulkomandy@pulkomandy.ath.cx>
* Oliver Tappe <zooey@hirschkaefer.de>
*/
/*
@@ -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,10 +237,12 @@ TimeZoneView::_InitView()
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 @@ TimeZoneView::_BuildRegionMenu()
// Now list the timezones for this country
BList tzList;
BTimeZone* timeZone;
TimeZoneListItem* countryItem;
switch (country.GetTimeZones(tzList))
{
@@ -257,30 +266,47 @@ TimeZoneView::_BuildRegionMenu()
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 @@ TimeZoneView::_SetPreview()
{
int32 selection = fCityList->CurrentSelection();
if (selection >= 0) {
TimeZoneListItem* item = (TimeZoneListItem*)fCityList->ItemAt(
selection);
// set timezone to selection
char buffer[50];
item->Code(buffer);
_SetTimeZone(buffer);
TimeZoneListItem* item
= (TimeZoneListItem*)fCityList->ItemAt(selection);
// calc preview time
time_t current = time(NULL);
time_t current = time(NULL) + item->OffsetFromGMT();
struct tm localTime;
localtime_r(&current, &localTime);
gmtime_r(&current, &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 @@ TimeZoneView::_SetPreview()
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 @@ TimeZoneView::_SetTimeZone()
if (selection < 0)
return;
char timeZoneCode[50];
((TimeZoneListItem*)fCityList->ItemAt(selection))->Code(timeZoneCode);
// update environment
_SetTimeZone(timeZoneCode);
const BString& code
= ((TimeZoneListItem*)fCityList->ItemAt(selection))->Code();
_SetTimeZone(code.String());
// update display
time_t current = time(NULL);
struct tm localTime;
localtime_r(&current, &localTime);
set_timezone(timeZoneCode);
set_timezone(code.String());
// disable button
fSetZone->SetEnabled(false);