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:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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(¤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 @@ 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(¤t, &localTime);
|
||||
|
||||
set_timezone(timeZoneCode);
|
||||
set_timezone(code.String());
|
||||
// disable button
|
||||
fSetZone->SetEnabled(false);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user