2 * Copyright 2004-2011, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
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"
19 #include <CalendarView.h>
22 #include <ControlLook.h>
26 #include <FindDirectory.h>
27 #include <LocaleRoster.h>
30 #include <StringView.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),
52 fSystemTimeAtStart(system_time())
56 // record the current time to enable revert.
61 DateTimeView::~DateTimeView()
67 DateTimeView::AttachedToWindow()
74 fCalendarView
->SetTarget(this);
80 DateTimeView::MessageReceived(BMessage
* message
)
83 switch (message
->what
) {
84 case B_OBSERVER_NOTICE_CHANGE
:
85 message
->FindInt32(B_OBSERVE_WHAT_CHANGE
, &change
);
88 _UpdateDateTime(message
);
92 BView::MessageReceived(message
);
97 case B_LOCALE_CHANGED
:
98 fCalendarView
->UpdateDayNameHeader();
103 BMessage
msg(*message
);
104 msg
.what
= H_USER_CHANGE
;
105 msg
.AddBool("time", false);
106 Window()->PostMessage(&msg
);
114 case kChangeTimeFinished
:
115 if (fClock
->IsChangingTime())
116 fTimeEdit
->MakeFocus(false);
117 fClock
->ChangeTimeFinished();
124 BView::MessageReceived(message
);
131 DateTimeView::CheckCanRevert()
133 // check for changed time
134 time_t unchangedNow
= fTimeAtStart
+ _PrefletUptime();
138 return changedNow
!= unchangedNow
;
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();
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,
159 dateTime
.SetTime(time
);
160 dateTime
.SetDate(date
);
162 set_real_time_clock(dateTime
.Time_t());
167 DateTimeView::_PrefletUptime() const
169 return (time_t)((system_time() - fSystemTimeAtStart
) / 1000000);
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
)
199 .AddGroup(B_VERTICAL
)
203 .SetInsets(B_USE_WINDOW_SPACING
, B_USE_WINDOW_SPACING
,
204 B_USE_WINDOW_SPACING
, B_USE_DEFAULT_SPACING
);
209 DateTimeView::_UpdateDateTime(BMessage
* message
)
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
);
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
);