From 53fcd8a4e50220d40a9ff402251dfe065b5ad692 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sun, 31 Mar 2013 18:22:09 +0200 Subject: [PATCH] DataField/RoughTime: render values in local time zone Implements TRAC ticket #2645. --- NEWS.txt | 1 + src/Dialogs/Task/Manager/TaskPropertiesPanel.cpp | 9 ++++++-- src/Dialogs/TimeEntry.cpp | 12 ++++++---- src/Dialogs/TimeEntry.hpp | 4 +++- src/Form/DataField/RoughTime.cpp | 12 ++++++++++ src/Form/DataField/RoughTime.hpp | 29 ++++++++++++++++++++---- src/Form/Edit.cpp | 2 +- src/Widget/RowFormWidget.cpp | 5 ++-- src/Widget/RowFormWidget.hpp | 3 ++- test/src/FakeDialogs.cpp | 4 +++- test/src/RunTextEntry.cpp | 4 +++- test/src/RunTimeEntry.cpp | 3 ++- 12 files changed, 69 insertions(+), 19 deletions(-) diff --git a/NEWS.txt b/NEWS.txt index 092f4950b..ffa15a5f7 100644 --- a/NEWS.txt +++ b/NEWS.txt @@ -32,6 +32,7 @@ Version 6.6 - not yet released - add AST point option "Score exit" (#2544) - optimise start point - allow up to 30 turn points in racing tasks + - local time for task start open/close time (#2645) * devices - Volkslogger: support IGC file download (#1972) - Volkslogger: declaration no longer erases waypoint database from logger diff --git a/src/Dialogs/Task/Manager/TaskPropertiesPanel.cpp b/src/Dialogs/Task/Manager/TaskPropertiesPanel.cpp index a357d7b50..349c5b576 100644 --- a/src/Dialogs/Task/Manager/TaskPropertiesPanel.cpp +++ b/src/Dialogs/Task/Manager/TaskPropertiesPanel.cpp @@ -33,6 +33,7 @@ Copyright_License { #include "Units/Units.hpp" #include "Language/Language.hpp" #include "Components.hpp" +#include "Interface.hpp" enum Controls { TASK_TYPE, @@ -227,8 +228,12 @@ TaskPropertiesPanel::Prepare(ContainerWindow &parent, const PixelRect &rc) AddTime(_("AAT min. time"), _("Minimum AAT task time in minutes."), 0, 36000, 60, 180); - AddRoughTime(_("Start open time"), nullptr, RoughTime::Invalid()); - AddRoughTime(_("Start close time"), nullptr, RoughTime::Invalid()); + const RoughTimeDelta time_zone = + CommonInterface::GetComputerSettings().utc_offset; + AddRoughTime(_("Start open time"), nullptr, + RoughTime::Invalid(), time_zone); + AddRoughTime(_("Start close time"), nullptr, + RoughTime::Invalid(), time_zone); AddFloat(_("Start max. speed"), _("Maximum speed allowed in start observation zone. Set to 0 for no limit."), diff --git a/src/Dialogs/TimeEntry.cpp b/src/Dialogs/TimeEntry.cpp index e525f728e..5535533b8 100644 --- a/src/Dialogs/TimeEntry.cpp +++ b/src/Dialogs/TimeEntry.cpp @@ -38,7 +38,8 @@ enum { }; bool -TimeEntryDialog(const TCHAR *caption, RoughTime &value, bool nullable) +TimeEntryDialog(const TCHAR *caption, RoughTime &value, + RoughTimeDelta time_zone, bool nullable) { /* create the dialog */ @@ -58,7 +59,7 @@ TimeEntryDialog(const TCHAR *caption, RoughTime &value, bool nullable) DigitEntry entry(look); entry.CreateTime(client_area, client_area.GetClientRect(), control_style); entry.Resize(entry.GetRecommendedSize()); - entry.SetValue(value); + entry.SetValue(value + time_zone); entry.SetActionListener(dialog, mrOK); /* create buttons */ @@ -66,9 +67,10 @@ TimeEntryDialog(const TCHAR *caption, RoughTime &value, bool nullable) dialog.AddButton(_("OK"), dialog, mrOK); dialog.AddButton(_("Cancel"), dialog, mrCancel); - auto now_listener = MakeLambdaActionListener([&entry](unsigned){ + auto now_listener = MakeLambdaActionListener([&entry, time_zone](unsigned){ const BrokenTime bt = BrokenDateTime::NowUTC(); - entry.SetValue(RoughTime(bt.hour, bt.minute)); + RoughTime now_utc = RoughTime(bt.hour, bt.minute); + entry.SetValue(now_utc + time_zone); }); dialog.AddButton(_("Now"), now_listener, 0); @@ -88,6 +90,6 @@ TimeEntryDialog(const TCHAR *caption, RoughTime &value, bool nullable) if (!result) return false; - value = entry.GetTimeValue(); + value = entry.GetTimeValue() - time_zone; return true; } diff --git a/src/Dialogs/TimeEntry.hpp b/src/Dialogs/TimeEntry.hpp index fb039038b..acbc1de4d 100644 --- a/src/Dialogs/TimeEntry.hpp +++ b/src/Dialogs/TimeEntry.hpp @@ -27,8 +27,10 @@ Copyright_License { #include class RoughTime; +class RoughTimeDelta; bool -TimeEntryDialog(const TCHAR *caption, RoughTime &value, bool nullable=false); +TimeEntryDialog(const TCHAR *caption, RoughTime &value, + RoughTimeDelta time_zone, bool nullable=false); #endif diff --git a/src/Form/DataField/RoughTime.cpp b/src/Form/DataField/RoughTime.cpp index 46fa5ac7b..d5389e919 100644 --- a/src/Form/DataField/RoughTime.cpp +++ b/src/Form/DataField/RoughTime.cpp @@ -57,6 +57,18 @@ RoughTimeDataField::GetAsString() const return buffer; } +const TCHAR * +RoughTimeDataField::GetAsDisplayString() const +{ + if (!value.IsValid()) + return _T(""); + + RoughTime local_value = value + time_zone; + _stprintf(buffer, _T("%02u:%02u"), + local_value.GetHour(), local_value.GetMinute()); + return buffer; +} + void RoughTimeDataField::Inc() { diff --git a/src/Form/DataField/RoughTime.hpp b/src/Form/DataField/RoughTime.hpp index 6ae72c520..6e75991f9 100644 --- a/src/Form/DataField/RoughTime.hpp +++ b/src/Form/DataField/RoughTime.hpp @@ -29,16 +29,32 @@ Copyright_License { #include "Compiler.h" /** - * This #DataField implementation stores a time of day with a - * precision of one minute. + * This #DataField implementation stores a UTC time of day with a + * precision of one minute. For displaying, it is converted to the + * user's time zone. */ class RoughTimeDataField : public DataField { RoughTime value; + /** + * This value is added when displaying the value to the user. It is + * the offset of the user's time zone. + */ + RoughTimeDelta time_zone; + public: - RoughTimeDataField(RoughTime _value, DataFieldListener *listener=nullptr) + RoughTimeDataField(RoughTime _value, RoughTimeDelta _time_zone, + DataFieldListener *listener=nullptr) :DataField(Type::ROUGH_TIME, false, listener), - value(_value) {} + value(_value), time_zone(_time_zone) {} + + RoughTimeDelta GetTimeZone() const { + return time_zone; + } + + void SetTimeZone(RoughTimeDelta _time_zone) { + time_zone = _time_zone; + } RoughTime GetValue() const { return value; @@ -48,11 +64,16 @@ public: value = _value; } + RoughTime GetLocalValue() const { + return value + time_zone; + } + void ModifyValue(RoughTime _value); /* virtual methods from class DataField */ virtual int GetAsInteger() const override; virtual const TCHAR *GetAsString() const override; + virtual const TCHAR *GetAsDisplayString() const override; virtual void Inc() override; virtual void Dec() override; diff --git a/src/Form/Edit.cpp b/src/Form/Edit.cpp index 339a9ca84..cd726aa24 100644 --- a/src/Form/Edit.cpp +++ b/src/Form/Edit.cpp @@ -188,7 +188,7 @@ WndProperty::BeginEditing() mDataField->GetType() == DataField::Type::ROUGH_TIME) { RoughTimeDataField &df = *(RoughTimeDataField *)mDataField; RoughTime value = df.GetValue(); - if (!TimeEntryDialog(GetCaption(), value, true)) + if (!TimeEntryDialog(GetCaption(), value, df.GetTimeZone(), true)) return true; df.ModifyValue(value); diff --git a/src/Widget/RowFormWidget.cpp b/src/Widget/RowFormWidget.cpp index 060696702..58202cb1f 100644 --- a/src/Widget/RowFormWidget.cpp +++ b/src/Widget/RowFormWidget.cpp @@ -419,10 +419,11 @@ RowFormWidget::AddTime(const TCHAR *label, const TCHAR *help, WndProperty * RowFormWidget::AddRoughTime(const TCHAR *label, const TCHAR *help, - RoughTime value, DataFieldListener *listener) + RoughTime value, RoughTimeDelta time_zone, + DataFieldListener *listener) { WndProperty *edit = Add(label, help); - RoughTimeDataField *df = new RoughTimeDataField(value, listener); + RoughTimeDataField *df = new RoughTimeDataField(value, time_zone, listener); edit->SetDataField(df); return edit; } diff --git a/src/Widget/RowFormWidget.hpp b/src/Widget/RowFormWidget.hpp index 6d3ba014b..09b153377 100644 --- a/src/Widget/RowFormWidget.hpp +++ b/src/Widget/RowFormWidget.hpp @@ -40,6 +40,7 @@ struct StaticEnumChoice; class ActionListener; class Angle; class RoughTime; +class RoughTimeDelta; /** * A #Widget that contains #WndProperty controls, one in a row. @@ -439,7 +440,7 @@ public: } WndProperty *AddRoughTime(const TCHAR *label, const TCHAR *help, - RoughTime value, + RoughTime value, RoughTimeDelta time_zone, DataFieldListener *listener=nullptr); void AddSpacer(); diff --git a/test/src/FakeDialogs.cpp b/test/src/FakeDialogs.cpp index 761cc9fb3..ad57d9b37 100644 --- a/test/src/FakeDialogs.cpp +++ b/test/src/FakeDialogs.cpp @@ -25,6 +25,7 @@ Copyright_License { #include "Dialogs/TextEntry.hpp" #include "Dialogs/TimeEntry.hpp" #include "Dialogs/GeoPointEntry.hpp" +#include "Time/RoughTime.hpp" int ShowMessageBox(const TCHAR *lpText, const TCHAR *lpCaption, unsigned uType) @@ -41,7 +42,8 @@ dlgTextEntryShowModal(TCHAR *text, size_t size, } bool -TimeEntryDialog(const TCHAR *caption, RoughTime &value, bool nullable) +TimeEntryDialog(const TCHAR *caption, RoughTime &value, + RoughTimeDelta time_zone, bool nullable) { return false; } diff --git a/test/src/RunTextEntry.cpp b/test/src/RunTextEntry.cpp index 9248d2332..253efc364 100644 --- a/test/src/RunTextEntry.cpp +++ b/test/src/RunTextEntry.cpp @@ -30,11 +30,13 @@ Copyright_License { #include "LocalPath.hpp" #include "Dialogs/TimeEntry.hpp" #include "Dialogs/GeoPointEntry.hpp" +#include "Time/RoughTime.hpp" void VisitDataFiles(const TCHAR* filter, File::Visitor &visitor) {} bool -TimeEntryDialog(const TCHAR *caption, RoughTime &value, bool nullable) +TimeEntryDialog(const TCHAR *caption, RoughTime &value, + RoughTimeDelta time_zone, bool nullable) { return false; } diff --git a/test/src/RunTimeEntry.cpp b/test/src/RunTimeEntry.cpp index a28ebf2da..64c45cd5b 100644 --- a/test/src/RunTimeEntry.cpp +++ b/test/src/RunTimeEntry.cpp @@ -34,7 +34,8 @@ static void Main() { RoughTime value = RoughTime::Invalid(); - if (!TimeEntryDialog(_T("The caption"), value, true)) + const RoughTimeDelta time_zone = RoughTimeDelta::FromMinutes(0); + if (!TimeEntryDialog(_T("The caption"), value, time_zone, true)) return; if (value.IsValid()) -- 2.11.4.GIT