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> 24e4289a54SKarsten Heimrich #include <Entry.h> 25e4289a54SKarsten Heimrich #include <File.h> 26e4289a54SKarsten Heimrich #include <FindDirectory.h> 27e4289a54SKarsten Heimrich #include <Message.h> 28e4289a54SKarsten Heimrich #include <Path.h> 29e4289a54SKarsten Heimrich #include <StringView.h> 30e4289a54SKarsten Heimrich #include <Window.h> 3138ac8defSOliver Tappe 32323ba9b7SRyan Leavengood #include "AnalogClock.h" 33323ba9b7SRyan Leavengood #include "DateTimeEdit.h" 34323ba9b7SRyan Leavengood #include "TimeMessages.h" 35323ba9b7SRyan Leavengood #include "TimeWindow.h" 36e4289a54SKarsten Heimrich 3738ac8defSOliver Tappe 38546208a5SOliver Tappe #undef B_TRANSLATION_CONTEXT 39546208a5SOliver Tappe #define B_TRANSLATION_CONTEXT "Time" 409717d515SJoachim Seemer 41e4289a54SKarsten Heimrich 4278092ae7SKarsten Heimrich using BPrivate::BCalendarView; 4378092ae7SKarsten Heimrich using BPrivate::BDateTime; 4478092ae7SKarsten Heimrich using BPrivate::B_LOCAL_TIME; 4578092ae7SKarsten Heimrich 4678092ae7SKarsten Heimrich 47323ba9b7SRyan Leavengood DateTimeView::DateTimeView(const char* name) 48323ba9b7SRyan Leavengood : 49323ba9b7SRyan Leavengood BGroupView(name, B_HORIZONTAL, 5), 501cae077aSStephan Aßmus fInitialized(false), 511cae077aSStephan Aßmus fSystemTimeAtStart(system_time()) 52e4289a54SKarsten Heimrich { 5385b69a94SKarsten Heimrich _InitView(); 541cae077aSStephan Aßmus 551cae077aSStephan Aßmus // record the current time to enable revert. 561cae077aSStephan Aßmus time(&fTimeAtStart); 57e4289a54SKarsten Heimrich } 58e4289a54SKarsten Heimrich 59e4289a54SKarsten Heimrich 60e4289a54SKarsten Heimrich DateTimeView::~DateTimeView() 61e4289a54SKarsten Heimrich { 62e4289a54SKarsten Heimrich } 63e4289a54SKarsten Heimrich 64e4289a54SKarsten Heimrich 65e4289a54SKarsten Heimrich void 66e4289a54SKarsten Heimrich DateTimeView::AttachedToWindow() 67e4289a54SKarsten Heimrich { 68e4289a54SKarsten Heimrich if (Parent()) 69e4289a54SKarsten Heimrich SetViewColor(Parent()->ViewColor()); 70e4289a54SKarsten Heimrich 71e4289a54SKarsten Heimrich if (!fInitialized) { 72e4289a54SKarsten Heimrich fInitialized = true; 7385b69a94SKarsten Heimrich 7485b69a94SKarsten Heimrich fCalendarView->SetTarget(this); 75e4289a54SKarsten Heimrich } 76e4289a54SKarsten Heimrich } 77e4289a54SKarsten Heimrich 78e4289a54SKarsten Heimrich 79e4289a54SKarsten Heimrich void 80e4289a54SKarsten Heimrich DateTimeView::MessageReceived(BMessage* message) 81e4289a54SKarsten Heimrich { 82e4289a54SKarsten Heimrich int32 change; 83e4289a54SKarsten Heimrich switch (message->what) { 84e4289a54SKarsten Heimrich case B_OBSERVER_NOTICE_CHANGE: 85e4289a54SKarsten Heimrich message->FindInt32(B_OBSERVE_WHAT_CHANGE, &change); 86e4289a54SKarsten Heimrich switch (change) { 87e4289a54SKarsten Heimrich case H_TM_CHANGED: 88e4289a54SKarsten Heimrich _UpdateDateTime(message); 89e4289a54SKarsten Heimrich break; 90e4289a54SKarsten Heimrich 91e4289a54SKarsten Heimrich default: 92e4289a54SKarsten Heimrich BView::MessageReceived(message); 93e4289a54SKarsten Heimrich break; 94e4289a54SKarsten Heimrich } 95e4289a54SKarsten Heimrich break; 96e4289a54SKarsten Heimrich 97e4289a54SKarsten Heimrich case kDayChanged: 98e4289a54SKarsten Heimrich { 99e4289a54SKarsten Heimrich BMessage msg(*message); 100e4289a54SKarsten Heimrich msg.what = H_USER_CHANGE; 101e4289a54SKarsten Heimrich msg.AddBool("time", false); 102e4289a54SKarsten Heimrich Window()->PostMessage(&msg); 1031cae077aSStephan Aßmus break; 1041cae077aSStephan Aßmus } 105e4289a54SKarsten Heimrich 1061cae077aSStephan Aßmus case kMsgRevert: 1071cae077aSStephan Aßmus _Revert(); 108e4289a54SKarsten Heimrich break; 109e4289a54SKarsten Heimrich 1103e58fe9eSStephan Aßmus case kChangeTimeFinished: 1113e58fe9eSStephan Aßmus if (fClock->IsChangingTime()) 1123e58fe9eSStephan Aßmus fTimeEdit->MakeFocus(false); 1133e58fe9eSStephan Aßmus fClock->ChangeTimeFinished(); 1143e58fe9eSStephan Aßmus break; 115d3bde5deSAxel Dörfler 116c2f3ee3bSAdrien Destugues case kRTCUpdate: 117c2f3ee3bSAdrien Destugues break; 118c2f3ee3bSAdrien Destugues 119e4289a54SKarsten Heimrich default: 120e4289a54SKarsten Heimrich BView::MessageReceived(message); 121e4289a54SKarsten Heimrich break; 122e4289a54SKarsten Heimrich } 123e4289a54SKarsten Heimrich } 124e4289a54SKarsten Heimrich 125e4289a54SKarsten Heimrich 126310930fdSStephan Aßmus bool 1271cae077aSStephan Aßmus DateTimeView::CheckCanRevert() 1281cae077aSStephan Aßmus { 1291cae077aSStephan Aßmus // check for changed time 1301cae077aSStephan Aßmus time_t unchangedNow = fTimeAtStart + _PrefletUptime(); 1311cae077aSStephan Aßmus time_t changedNow; 1321cae077aSStephan Aßmus time(&changedNow); 1331cae077aSStephan Aßmus 134c2f3ee3bSAdrien Destugues return changedNow != unchangedNow; 1351cae077aSStephan Aßmus } 1361cae077aSStephan Aßmus 1371cae077aSStephan Aßmus 1381cae077aSStephan Aßmus void 1391cae077aSStephan Aßmus DateTimeView::_Revert() 1401cae077aSStephan Aßmus { 1411cae077aSStephan Aßmus // Set the clock and calendar as they were at launch time + 142d3bde5deSAxel Dörfler // time elapsed since application launch. 1431cae077aSStephan Aßmus 1441cae077aSStephan Aßmus time_t timeNow = fTimeAtStart + _PrefletUptime(); 1451cae077aSStephan Aßmus struct tm result; 1461cae077aSStephan Aßmus struct tm* timeInfo; 1471cae077aSStephan Aßmus timeInfo = localtime_r(&timeNow, &result); 1481cae077aSStephan Aßmus 1491cae077aSStephan Aßmus BDateTime dateTime = BDateTime::CurrentDateTime(B_LOCAL_TIME); 1501cae077aSStephan Aßmus BTime time = dateTime.Time(); 1511cae077aSStephan Aßmus BDate date = dateTime.Date(); 1521cae077aSStephan Aßmus time.SetTime(timeInfo->tm_hour, timeInfo->tm_min, timeInfo->tm_sec % 60); 1531cae077aSStephan Aßmus date.SetDate(timeInfo->tm_year + 1900, timeInfo->tm_mon + 1, 1541cae077aSStephan Aßmus timeInfo->tm_mday); 1551cae077aSStephan Aßmus dateTime.SetTime(time); 1561cae077aSStephan Aßmus dateTime.SetDate(date); 1571cae077aSStephan Aßmus 1581cae077aSStephan Aßmus set_real_time_clock(dateTime.Time_t()); 1591cae077aSStephan Aßmus } 1601cae077aSStephan Aßmus 1611cae077aSStephan Aßmus 1621cae077aSStephan Aßmus time_t 1631cae077aSStephan Aßmus DateTimeView::_PrefletUptime() const 1641cae077aSStephan Aßmus { 1651cae077aSStephan Aßmus return (time_t)((system_time() - fSystemTimeAtStart) / 1000000); 1661cae077aSStephan Aßmus } 1671cae077aSStephan Aßmus 1681cae077aSStephan Aßmus 1691cae077aSStephan Aßmus void 170e4289a54SKarsten Heimrich DateTimeView::_InitView() 171e4289a54SKarsten Heimrich { 1726846765fSOliver Tappe fCalendarView = new BCalendarView("calendar"); 173e4289a54SKarsten Heimrich fCalendarView->SetWeekNumberHeaderVisible(false); 174e4289a54SKarsten Heimrich fCalendarView->SetSelectionMessage(new BMessage(kDayChanged)); 175e4289a54SKarsten Heimrich fCalendarView->SetInvocationMessage(new BMessage(kDayChanged)); 176e4289a54SKarsten Heimrich 177323ba9b7SRyan Leavengood fDateEdit = new TDateEdit("dateEdit", 3); 178*91a14c7cSJanus fTimeEdit = new TTimeEdit("timeEdit", 5); 179323ba9b7SRyan Leavengood fClock = new TAnalogClock("analogClock"); 180e4289a54SKarsten Heimrich 18178092ae7SKarsten Heimrich BTime time(BTime::CurrentTime(B_LOCAL_TIME)); 18278092ae7SKarsten Heimrich fClock->SetTime(time.Hour(), time.Minute(), time.Second()); 183e4289a54SKarsten Heimrich 184323ba9b7SRyan Leavengood BBox* divider = new BBox(BRect(0, 0, 1, 1), 185323ba9b7SRyan Leavengood B_EMPTY_STRING, B_FOLLOW_ALL_SIDES, 186323ba9b7SRyan Leavengood B_WILL_DRAW | B_FRAME_EVENTS, B_FANCY_BORDER); 187323ba9b7SRyan Leavengood divider->SetExplicitMaxSize(BSize(1, B_SIZE_UNLIMITED)); 188323ba9b7SRyan Leavengood 189ad926b25SHumdinger BLayoutBuilder::Group<>(this, B_HORIZONTAL, B_USE_DEFAULT_SPACING) 190ad926b25SHumdinger .AddGroup(B_VERTICAL, B_USE_DEFAULT_SPACING) 191323ba9b7SRyan Leavengood .Add(fDateEdit) 192323ba9b7SRyan Leavengood .Add(fCalendarView) 193323ba9b7SRyan Leavengood .End() 194323ba9b7SRyan Leavengood .Add(divider) 195ad926b25SHumdinger .AddGroup(B_VERTICAL) 196323ba9b7SRyan Leavengood .Add(fTimeEdit) 197323ba9b7SRyan Leavengood .Add(fClock) 198323ba9b7SRyan Leavengood .End() 199ad926b25SHumdinger .SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING, 200ad926b25SHumdinger B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING); 201e4289a54SKarsten Heimrich } 202e4289a54SKarsten Heimrich 203e4289a54SKarsten Heimrich 204e4289a54SKarsten Heimrich void 205e4289a54SKarsten Heimrich DateTimeView::_UpdateDateTime(BMessage* message) 206e4289a54SKarsten Heimrich { 207e4289a54SKarsten Heimrich int32 day; 208e4289a54SKarsten Heimrich int32 month; 209e4289a54SKarsten Heimrich int32 year; 210e4289a54SKarsten Heimrich if (message->FindInt32("month", &month) == B_OK 211e4289a54SKarsten Heimrich && message->FindInt32("day", &day) == B_OK 212d3bde5deSAxel Dörfler && message->FindInt32("year", &year) == B_OK) { 2136846765fSOliver Tappe static int32 lastDay; 2146846765fSOliver Tappe static int32 lastMonth; 2156846765fSOliver Tappe static int32 lastYear; 2166846765fSOliver Tappe if (day != lastDay || month != lastMonth || year != lastYear) { 217e4289a54SKarsten Heimrich fDateEdit->SetDate(year, month, day); 218e4289a54SKarsten Heimrich fCalendarView->SetDate(year, month, day); 2196846765fSOliver Tappe lastDay = day; 2206846765fSOliver Tappe lastMonth = month; 2216846765fSOliver Tappe lastYear = year; 2226846765fSOliver Tappe } 223e4289a54SKarsten Heimrich } 224e4289a54SKarsten Heimrich 225e4289a54SKarsten Heimrich int32 hour; 226e4289a54SKarsten Heimrich int32 minute; 227e4289a54SKarsten Heimrich int32 second; 228e4289a54SKarsten Heimrich if (message->FindInt32("hour", &hour) == B_OK 229e4289a54SKarsten Heimrich && message->FindInt32("minute", &minute) == B_OK 230d3bde5deSAxel Dörfler && message->FindInt32("second", &second) == B_OK) { 231e4289a54SKarsten Heimrich fClock->SetTime(hour, minute, second); 23285b69a94SKarsten Heimrich fTimeEdit->SetTime(hour, minute, second); 233e4289a54SKarsten Heimrich } 234e4289a54SKarsten Heimrich } 235f64b502dSRyan Leavengood 236