Fix FreeBSD build.
[haiku.git] / src / preferences / time / DateTimeView.cpp
blob9f19b75f2afb62b5c741b1549edf0524a3945072
1 /*
2 * Copyright 2004-2011, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Andrew McCall <mccall@@digitalparadise.co.uk>
7 * Mike Berg <mike@berg-net.us>
8 * Julun <host.haiku@gmx.de>
9 * Philippe Saint-Pierre <stpere@gmail.com>
10 * Hamish Morrison <hamish@lavabit.com>
13 #include "DateTimeView.h"
15 #include <time.h>
16 #include <syscalls.h>
18 #include <Box.h>
19 #include <CalendarView.h>
20 #include <Catalog.h>
21 #include <CheckBox.h>
22 #include <ControlLook.h>
23 #include <DateTime.h>
24 #include <Entry.h>
25 #include <File.h>
26 #include <FindDirectory.h>
27 #include <LocaleRoster.h>
28 #include <Message.h>
29 #include <Path.h>
30 #include <StringView.h>
31 #include <Window.h>
33 #include "AnalogClock.h"
34 #include "DateTimeEdit.h"
35 #include "TimeMessages.h"
36 #include "TimeWindow.h"
39 #undef B_TRANSLATION_CONTEXT
40 #define B_TRANSLATION_CONTEXT "Time"
43 using BPrivate::BCalendarView;
44 using BPrivate::BDateTime;
45 using BPrivate::B_LOCAL_TIME;
48 DateTimeView::DateTimeView(const char* name)
50 BGroupView(name, B_HORIZONTAL, 5),
51 fInitialized(false),
52 fSystemTimeAtStart(system_time())
54 _InitView();
56 // record the current time to enable revert.
57 time(&fTimeAtStart);
61 DateTimeView::~DateTimeView()
66 void
67 DateTimeView::AttachedToWindow()
69 AdoptParentColors();
71 if (!fInitialized) {
72 fInitialized = true;
74 fCalendarView->SetTarget(this);
79 void
80 DateTimeView::MessageReceived(BMessage* message)
82 int32 change;
83 switch (message->what) {
84 case B_OBSERVER_NOTICE_CHANGE:
85 message->FindInt32(B_OBSERVE_WHAT_CHANGE, &change);
86 switch (change) {
87 case H_TM_CHANGED:
88 _UpdateDateTime(message);
89 break;
91 default:
92 BView::MessageReceived(message);
93 break;
95 break;
97 case B_LOCALE_CHANGED:
98 fCalendarView->UpdateDayNameHeader();
99 break;
101 case kDayChanged:
103 BMessage msg(*message);
104 msg.what = H_USER_CHANGE;
105 msg.AddBool("time", false);
106 Window()->PostMessage(&msg);
107 break;
110 case kMsgRevert:
111 _Revert();
112 break;
114 case kChangeTimeFinished:
115 if (fClock->IsChangingTime())
116 fTimeEdit->MakeFocus(false);
117 fClock->ChangeTimeFinished();
118 break;
120 case kRTCUpdate:
121 break;
123 default:
124 BView::MessageReceived(message);
125 break;
130 bool
131 DateTimeView::CheckCanRevert()
133 // check for changed time
134 time_t unchangedNow = fTimeAtStart + _PrefletUptime();
135 time_t changedNow;
136 time(&changedNow);
138 return changedNow != unchangedNow;
142 void
143 DateTimeView::_Revert()
145 // Set the clock and calendar as they were at launch time +
146 // time elapsed since application launch.
148 time_t timeNow = fTimeAtStart + _PrefletUptime();
149 struct tm result;
150 struct tm* timeInfo;
151 timeInfo = localtime_r(&timeNow, &result);
153 BDateTime dateTime = BDateTime::CurrentDateTime(B_LOCAL_TIME);
154 BTime time = dateTime.Time();
155 BDate date = dateTime.Date();
156 time.SetTime(timeInfo->tm_hour, timeInfo->tm_min, timeInfo->tm_sec % 60);
157 date.SetDate(timeInfo->tm_year + 1900, timeInfo->tm_mon + 1,
158 timeInfo->tm_mday);
159 dateTime.SetTime(time);
160 dateTime.SetDate(date);
162 set_real_time_clock(dateTime.Time_t());
166 time_t
167 DateTimeView::_PrefletUptime() const
169 return (time_t)((system_time() - fSystemTimeAtStart) / 1000000);
173 void
174 DateTimeView::_InitView()
176 fCalendarView = new BCalendarView("calendar");
177 fCalendarView->SetWeekNumberHeaderVisible(false);
178 fCalendarView->SetSelectionMessage(new BMessage(kDayChanged));
179 fCalendarView->SetInvocationMessage(new BMessage(kDayChanged));
181 fDateEdit = new TDateEdit("dateEdit", 3);
182 fTimeEdit = new TTimeEdit("timeEdit", 5);
183 fClock = new TAnalogClock("analogClock");
185 BTime time(BTime::CurrentTime(B_LOCAL_TIME));
186 fClock->SetTime(time.Hour(), time.Minute(), time.Second());
188 BBox* divider = new BBox(BRect(0, 0, 1, 1),
189 B_EMPTY_STRING, B_FOLLOW_ALL_SIDES,
190 B_WILL_DRAW | B_FRAME_EVENTS, B_FANCY_BORDER);
191 divider->SetExplicitMaxSize(BSize(1, B_SIZE_UNLIMITED));
193 BLayoutBuilder::Group<>(this, B_HORIZONTAL, B_USE_DEFAULT_SPACING)
194 .AddGroup(B_VERTICAL, B_USE_DEFAULT_SPACING)
195 .Add(fDateEdit)
196 .Add(fCalendarView)
197 .End()
198 .Add(divider)
199 .AddGroup(B_VERTICAL)
200 .Add(fTimeEdit)
201 .Add(fClock)
202 .End()
203 .SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING,
204 B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING);
208 void
209 DateTimeView::_UpdateDateTime(BMessage* message)
211 int32 day;
212 int32 month;
213 int32 year;
214 if (message->FindInt32("month", &month) == B_OK
215 && message->FindInt32("day", &day) == B_OK
216 && message->FindInt32("year", &year) == B_OK) {
217 static int32 lastDay;
218 static int32 lastMonth;
219 static int32 lastYear;
220 if (day != lastDay || month != lastMonth || year != lastYear) {
221 fDateEdit->SetDate(year, month, day);
222 fCalendarView->SetDate(year, month, day);
223 lastDay = day;
224 lastMonth = month;
225 lastYear = year;
229 int32 hour;
230 int32 minute;
231 int32 second;
232 if (message->FindInt32("hour", &hour) == B_OK
233 && message->FindInt32("minute", &minute) == B_OK
234 && message->FindInt32("second", &second) == B_OK) {
235 fClock->SetTime(hour, minute, second);
236 fTimeEdit->SetTime(hour, minute, second);