1e4289a54SKarsten Heimrich /* 2323ba9b7SRyan Leavengood * Copyright 2004-2011, Haiku, Inc. All Rights Reserved. 3e4289a54SKarsten Heimrich * Distributed under the terms of the MIT License. 4e4289a54SKarsten Heimrich * 5e4289a54SKarsten Heimrich * Authors: 6e4289a54SKarsten Heimrich * Andrew McCall <mccall@@digitalparadise.co.uk> 7e4289a54SKarsten Heimrich * Mike Berg <mike@berg-net.us> 8e4289a54SKarsten Heimrich * Julun <host.haiku@gmx.de> 91cae077aSStephan Aßmus * Philippe Saint-Pierre <stpere@gmail.com> 10323ba9b7SRyan Leavengood * Hamish Morrison <hamish@lavabit.com> 11e4289a54SKarsten Heimrich */ 12e4289a54SKarsten Heimrich 13e4289a54SKarsten Heimrich #include "DateTimeView.h" 14e4289a54SKarsten Heimrich 15323ba9b7SRyan Leavengood #include <time.h> 16323ba9b7SRyan Leavengood #include <syscalls.h> 17323ba9b7SRyan Leavengood 18323ba9b7SRyan Leavengood #include <Box.h> 1978092ae7SKarsten Heimrich #include <CalendarView.h> 209717d515SJoachim Seemer #include <Catalog.h> 21e4289a54SKarsten Heimrich #include <CheckBox.h> 22365839fbSRyan Leavengood #include <ControlLook.h> 2378092ae7SKarsten Heimrich #include <DateTime.h> 24*cc9bc8c6SJaidyn Ann #include <DateTimeEdit.h> 25e4289a54SKarsten Heimrich #include <Entry.h> 26e4289a54SKarsten Heimrich #include <File.h> 27e4289a54SKarsten Heimrich #include <FindDirectory.h> 289dc78758SAkshay Agarwal #include <LocaleRoster.h> 29e4289a54SKarsten Heimrich #include <Message.h> 30e4289a54SKarsten Heimrich #include <Path.h> 31e4289a54SKarsten Heimrich #include <StringView.h> 32e4289a54SKarsten Heimrich #include <Window.h> 3338ac8defSOliver Tappe 34323ba9b7SRyan Leavengood #include "AnalogClock.h" 35323ba9b7SRyan Leavengood #include "TimeMessages.h" 36323ba9b7SRyan Leavengood #include "TimeWindow.h" 37e4289a54SKarsten Heimrich 3838ac8defSOliver Tappe 39546208a5SOliver Tappe #undef B_TRANSLATION_CONTEXT 40546208a5SOliver Tappe #define B_TRANSLATION_CONTEXT "Time" 419717d515SJoachim Seemer 42e4289a54SKarsten Heimrich 4378092ae7SKarsten Heimrich using BPrivate::BCalendarView; 4478092ae7SKarsten Heimrich using BPrivate::BDateTime; 4578092ae7SKarsten Heimrich using BPrivate::B_LOCAL_TIME; 46*cc9bc8c6SJaidyn Ann using BPrivate::DateEdit; 47*cc9bc8c6SJaidyn Ann using BPrivate::TimeEdit; 4878092ae7SKarsten Heimrich 4978092ae7SKarsten Heimrich 50323ba9b7SRyan Leavengood DateTimeView::DateTimeView(const char* name) 51323ba9b7SRyan Leavengood : 52323ba9b7SRyan Leavengood BGroupView(name, B_HORIZONTAL, 5), 531cae077aSStephan Aßmus fInitialized(false), 541cae077aSStephan Aßmus fSystemTimeAtStart(system_time()) 55e4289a54SKarsten Heimrich { 5685b69a94SKarsten Heimrich _InitView(); 571cae077aSStephan Aßmus 581cae077aSStephan Aßmus // record the current time to enable revert. 591cae077aSStephan Aßmus time(&fTimeAtStart); 60e4289a54SKarsten Heimrich } 61e4289a54SKarsten Heimrich 62e4289a54SKarsten Heimrich 63e4289a54SKarsten Heimrich DateTimeView::~DateTimeView() 64e4289a54SKarsten Heimrich { 65e4289a54SKarsten Heimrich } 66e4289a54SKarsten Heimrich 67e4289a54SKarsten Heimrich 68e4289a54SKarsten Heimrich void 69e4289a54SKarsten Heimrich DateTimeView::AttachedToWindow() 70e4289a54SKarsten Heimrich { 71f0650dc9Slooncraz AdoptParentColors(); 72e4289a54SKarsten Heimrich 73e4289a54SKarsten Heimrich if (!fInitialized) { 74e4289a54SKarsten Heimrich fInitialized = true; 7585b69a94SKarsten Heimrich 7685b69a94SKarsten Heimrich fCalendarView->SetTarget(this); 77e4289a54SKarsten Heimrich } 78e4289a54SKarsten Heimrich } 79e4289a54SKarsten Heimrich 80e4289a54SKarsten Heimrich 81e4289a54SKarsten Heimrich void 82e4289a54SKarsten Heimrich DateTimeView::MessageReceived(BMessage* message) 83e4289a54SKarsten Heimrich { 84e4289a54SKarsten Heimrich int32 change; 85e4289a54SKarsten Heimrich switch (message->what) { 86e4289a54SKarsten Heimrich case B_OBSERVER_NOTICE_CHANGE: 87e4289a54SKarsten Heimrich message->FindInt32(B_OBSERVE_WHAT_CHANGE, &change); 88e4289a54SKarsten Heimrich switch (change) { 89e4289a54SKarsten Heimrich case H_TM_CHANGED: 90e4289a54SKarsten Heimrich _UpdateDateTime(message); 91e4289a54SKarsten Heimrich break; 92e4289a54SKarsten Heimrich 93e4289a54SKarsten Heimrich default: 94e4289a54SKarsten Heimrich BView::MessageReceived(message); 95e4289a54SKarsten Heimrich break; 96e4289a54SKarsten Heimrich } 97e4289a54SKarsten Heimrich break; 98e4289a54SKarsten Heimrich 999dc78758SAkshay Agarwal case B_LOCALE_CHANGED: 1009dc78758SAkshay Agarwal fCalendarView->UpdateDayNameHeader(); 1019dc78758SAkshay Agarwal break; 1029dc78758SAkshay Agarwal 103e4289a54SKarsten Heimrich case kDayChanged: 104e4289a54SKarsten Heimrich { 105e4289a54SKarsten Heimrich BMessage msg(*message); 106e4289a54SKarsten Heimrich msg.what = H_USER_CHANGE; 107e4289a54SKarsten Heimrich msg.AddBool("time", false); 108e4289a54SKarsten Heimrich Window()->PostMessage(&msg); 1091cae077aSStephan Aßmus break; 1101cae077aSStephan Aßmus } 111e4289a54SKarsten Heimrich 1121cae077aSStephan Aßmus case kMsgRevert: 1131cae077aSStephan Aßmus _Revert(); 114e4289a54SKarsten Heimrich break; 115e4289a54SKarsten Heimrich 1163e58fe9eSStephan Aßmus case kChangeTimeFinished: 1173e58fe9eSStephan Aßmus if (fClock->IsChangingTime()) 1183e58fe9eSStephan Aßmus fTimeEdit->MakeFocus(false); 1193e58fe9eSStephan Aßmus fClock->ChangeTimeFinished(); 1203e58fe9eSStephan Aßmus break; 121d3bde5deSAxel Dörfler 122c2f3ee3bSAdrien Destugues case kRTCUpdate: 123c2f3ee3bSAdrien Destugues break; 124c2f3ee3bSAdrien Destugues 125e4289a54SKarsten Heimrich default: 126e4289a54SKarsten Heimrich BView::MessageReceived(message); 127e4289a54SKarsten Heimrich break; 128e4289a54SKarsten Heimrich } 129e4289a54SKarsten Heimrich } 130e4289a54SKarsten Heimrich 131e4289a54SKarsten Heimrich 132310930fdSStephan Aßmus bool 1331cae077aSStephan Aßmus DateTimeView::CheckCanRevert() 1341cae077aSStephan Aßmus { 1351cae077aSStephan Aßmus // check for changed time 1361cae077aSStephan Aßmus time_t unchangedNow = fTimeAtStart + _PrefletUptime(); 1371cae077aSStephan Aßmus time_t changedNow; 1381cae077aSStephan Aßmus time(&changedNow); 1391cae077aSStephan Aßmus 140c2f3ee3bSAdrien Destugues return changedNow != unchangedNow; 1411cae077aSStephan Aßmus } 1421cae077aSStephan Aßmus 1431cae077aSStephan Aßmus 1441cae077aSStephan Aßmus void 1451cae077aSStephan Aßmus DateTimeView::_Revert() 1461cae077aSStephan Aßmus { 1471cae077aSStephan Aßmus // Set the clock and calendar as they were at launch time + 148d3bde5deSAxel Dörfler // time elapsed since application launch. 1491cae077aSStephan Aßmus 1501cae077aSStephan Aßmus time_t timeNow = fTimeAtStart + _PrefletUptime(); 1511cae077aSStephan Aßmus struct tm result; 1521cae077aSStephan Aßmus struct tm* timeInfo; 1531cae077aSStephan Aßmus timeInfo = localtime_r(&timeNow, &result); 1541cae077aSStephan Aßmus 1551cae077aSStephan Aßmus BDateTime dateTime = BDateTime::CurrentDateTime(B_LOCAL_TIME); 1561cae077aSStephan Aßmus BTime time = dateTime.Time(); 1571cae077aSStephan Aßmus BDate date = dateTime.Date(); 1581cae077aSStephan Aßmus time.SetTime(timeInfo->tm_hour, timeInfo->tm_min, timeInfo->tm_sec % 60); 1591cae077aSStephan Aßmus date.SetDate(timeInfo->tm_year + 1900, timeInfo->tm_mon + 1, 1601cae077aSStephan Aßmus timeInfo->tm_mday); 1611cae077aSStephan Aßmus dateTime.SetTime(time); 1621cae077aSStephan Aßmus dateTime.SetDate(date); 1631cae077aSStephan Aßmus 1641cae077aSStephan Aßmus set_real_time_clock(dateTime.Time_t()); 1651cae077aSStephan Aßmus } 1661cae077aSStephan Aßmus 1671cae077aSStephan Aßmus 1681cae077aSStephan Aßmus time_t 1691cae077aSStephan Aßmus DateTimeView::_PrefletUptime() const 1701cae077aSStephan Aßmus { 1711cae077aSStephan Aßmus return (time_t)((system_time() - fSystemTimeAtStart) / 1000000); 1721cae077aSStephan Aßmus } 1731cae077aSStephan Aßmus 1741cae077aSStephan Aßmus 1751cae077aSStephan Aßmus void 176e4289a54SKarsten Heimrich DateTimeView::_InitView() 177e4289a54SKarsten Heimrich { 1786846765fSOliver Tappe fCalendarView = new BCalendarView("calendar"); 179e4289a54SKarsten Heimrich fCalendarView->SetWeekNumberHeaderVisible(false); 180e4289a54SKarsten Heimrich fCalendarView->SetSelectionMessage(new BMessage(kDayChanged)); 181e4289a54SKarsten Heimrich fCalendarView->SetInvocationMessage(new BMessage(kDayChanged)); 182e4289a54SKarsten Heimrich 183*cc9bc8c6SJaidyn Ann fDateEdit = new DateEdit("dateEdit", 3, new BMessage(H_USER_CHANGE)); 184*cc9bc8c6SJaidyn Ann fTimeEdit = new TimeEdit("timeEdit", 5, new BMessage(H_USER_CHANGE)); 185323ba9b7SRyan Leavengood fClock = new TAnalogClock("analogClock"); 186e4289a54SKarsten Heimrich 18778092ae7SKarsten Heimrich BTime time(BTime::CurrentTime(B_LOCAL_TIME)); 18878092ae7SKarsten Heimrich fClock->SetTime(time.Hour(), time.Minute(), time.Second()); 189e4289a54SKarsten Heimrich 190323ba9b7SRyan Leavengood BBox* divider = new BBox(BRect(0, 0, 1, 1), 191323ba9b7SRyan Leavengood B_EMPTY_STRING, B_FOLLOW_ALL_SIDES, 192323ba9b7SRyan Leavengood B_WILL_DRAW | B_FRAME_EVENTS, B_FANCY_BORDER); 193323ba9b7SRyan Leavengood divider->SetExplicitMaxSize(BSize(1, B_SIZE_UNLIMITED)); 194323ba9b7SRyan Leavengood 195ad926b25SHumdinger BLayoutBuilder::Group<>(this, B_HORIZONTAL, B_USE_DEFAULT_SPACING) 196ad926b25SHumdinger .AddGroup(B_VERTICAL, B_USE_DEFAULT_SPACING) 197323ba9b7SRyan Leavengood .Add(fDateEdit) 198323ba9b7SRyan Leavengood .Add(fCalendarView) 199323ba9b7SRyan Leavengood .End() 200323ba9b7SRyan Leavengood .Add(divider) 201ad926b25SHumdinger .AddGroup(B_VERTICAL) 202323ba9b7SRyan Leavengood .Add(fTimeEdit) 203323ba9b7SRyan Leavengood .Add(fClock) 204323ba9b7SRyan Leavengood .End() 205ad926b25SHumdinger .SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING, 206ad926b25SHumdinger B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING); 207e4289a54SKarsten Heimrich } 208e4289a54SKarsten Heimrich 209e4289a54SKarsten Heimrich 210e4289a54SKarsten Heimrich void 211e4289a54SKarsten Heimrich DateTimeView::_UpdateDateTime(BMessage* message) 212e4289a54SKarsten Heimrich { 213e4289a54SKarsten Heimrich int32 day; 214e4289a54SKarsten Heimrich int32 month; 215e4289a54SKarsten Heimrich int32 year; 216e4289a54SKarsten Heimrich if (message->FindInt32("month", &month) == B_OK 217e4289a54SKarsten Heimrich && message->FindInt32("day", &day) == B_OK 218d3bde5deSAxel Dörfler && message->FindInt32("year", &year) == B_OK) { 2196846765fSOliver Tappe static int32 lastDay; 2206846765fSOliver Tappe static int32 lastMonth; 2216846765fSOliver Tappe static int32 lastYear; 2226846765fSOliver Tappe if (day != lastDay || month != lastMonth || year != lastYear) { 223e4289a54SKarsten Heimrich fDateEdit->SetDate(year, month, day); 224e4289a54SKarsten Heimrich fCalendarView->SetDate(year, month, day); 2256846765fSOliver Tappe lastDay = day; 2266846765fSOliver Tappe lastMonth = month; 2276846765fSOliver Tappe lastYear = year; 2286846765fSOliver Tappe } 229e4289a54SKarsten Heimrich } 230e4289a54SKarsten Heimrich 231e4289a54SKarsten Heimrich int32 hour; 232e4289a54SKarsten Heimrich int32 minute; 233e4289a54SKarsten Heimrich int32 second; 234e4289a54SKarsten Heimrich if (message->FindInt32("hour", &hour) == B_OK 235e4289a54SKarsten Heimrich && message->FindInt32("minute", &minute) == B_OK 236d3bde5deSAxel Dörfler && message->FindInt32("second", &second) == B_OK) { 237e4289a54SKarsten Heimrich fClock->SetTime(hour, minute, second); 23885b69a94SKarsten Heimrich fTimeEdit->SetTime(hour, minute, second); 239e4289a54SKarsten Heimrich } 240e4289a54SKarsten Heimrich } 241f64b502dSRyan Leavengood 242