1 /* 2 * Copyright 2004-2007, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Andrew McCall <mccall@@digitalparadise.co.uk> 7 * Mike Berg <mike@berg-net.us> 8 * Julun <host.haiku@gmx.de> 9 */ 10 11 #include "DateTimeView.h" 12 #include "AnalogClock.h" 13 #include "CalendarView.h" 14 #include "DateTimeEdit.h" 15 #include "TimeMessages.h" 16 17 18 #include <CheckBox.h> 19 #include <Entry.h> 20 #include <File.h> 21 #include <FindDirectory.h> 22 #include <Message.h> 23 #include <Path.h> 24 #include <RadioButton.h> 25 #include <String.h> 26 #include <StringView.h> 27 #include <Window.h> 28 29 30 #ifdef HAIKU_TARGET_PLATFORM_HAIKU 31 # include <syscalls.h> 32 #else 33 extern "C" void _kset_tzfilename_(const char *name, size_t length, bool isGMT); 34 # define _kern_set_tzfilename _kset_tzfilename_ 35 #endif 36 37 38 DateTimeView::DateTimeView(BRect frame) 39 : BView(frame, "dateTimeView", B_FOLLOW_NONE, B_WILL_DRAW | B_NAVIGABLE_JUMP), 40 fGmtTime(NULL), 41 fUseGmtTime(false), 42 fInitialized(false) 43 { 44 _ReadRTCSettings(); 45 _InitView(); 46 } 47 48 49 DateTimeView::~DateTimeView() 50 { 51 _WriteRTCSettings(); 52 } 53 54 55 void 56 DateTimeView::AttachedToWindow() 57 { 58 if (Parent()) 59 SetViewColor(Parent()->ViewColor()); 60 61 if (!fInitialized) { 62 fInitialized = true; 63 64 fGmtTime->SetTarget(this); 65 fLocalTime->SetTarget(this); 66 fCalendarView->SetTarget(this); 67 } 68 } 69 70 71 void 72 DateTimeView::Draw(BRect /*updateRect*/) 73 { 74 rgb_color viewcolor = ViewColor(); 75 rgb_color dark = tint_color(viewcolor, B_DARKEN_4_TINT); 76 rgb_color light = tint_color(viewcolor, B_LIGHTEN_MAX_TINT); 77 78 //draw a separator line 79 BRect bounds(Bounds()); 80 BPoint start(bounds.Width() / 2.0f, bounds.top + 5.0f); 81 BPoint end(bounds.Width() / 2.0, bounds.bottom - 5.0f); 82 83 BeginLineArray(2); 84 AddLine(start, end, dark); 85 start.x++; 86 end.x++; 87 AddLine(start, end, light); 88 EndLineArray(); 89 90 fTimeEdit->Draw(bounds); 91 fDateEdit->Draw(bounds); 92 } 93 94 95 void 96 DateTimeView::MessageReceived(BMessage *message) 97 { 98 int32 change; 99 switch(message->what) { 100 case B_OBSERVER_NOTICE_CHANGE: 101 message->FindInt32(B_OBSERVE_WHAT_CHANGE, &change); 102 switch(change) { 103 case H_TM_CHANGED: 104 _UpdateDateTime(message); 105 break; 106 107 default: 108 BView::MessageReceived(message); 109 break; 110 } 111 break; 112 113 case kDayChanged: 114 { 115 BMessage msg(*message); 116 msg.what = H_USER_CHANGE; 117 msg.AddBool("time", false); 118 Window()->PostMessage(&msg); 119 } break; 120 121 case kRTCUpdate: 122 fUseGmtTime = !fUseGmtTime; 123 _UpdateGmtSettings(); 124 break; 125 126 default: 127 BView::MessageReceived(message); 128 break; 129 } 130 } 131 132 133 void 134 DateTimeView::_InitView() 135 { 136 font_height fontHeight; 137 be_plain_font->GetHeight(&fontHeight); 138 float textHeight = fontHeight.descent + fontHeight.ascent 139 + fontHeight.leading + 6.0; // 6px border 140 141 // left side 142 BRect bounds = Bounds(); 143 bounds.InsetBy(10.0, 10.0); 144 bounds.top += textHeight + 10.0; 145 146 fCalendarView = new BCalendarView(bounds, "calendar"); 147 fCalendarView->SetWeekNumberHeaderVisible(false); 148 fCalendarView->ResizeToPreferred(); 149 fCalendarView->SetSelectionMessage(new BMessage(kDayChanged)); 150 fCalendarView->SetInvocationMessage(new BMessage(kDayChanged)); 151 152 bounds.top -= textHeight + 10.0; 153 bounds.bottom = bounds.top + textHeight; 154 bounds.right = fCalendarView->Frame().right; 155 156 fDateEdit = new TDateEdit(bounds, "dateEdit", 3); 157 AddChild(fDateEdit); 158 AddChild(fCalendarView); 159 160 // right side, 2px extra for separator 161 bounds.OffsetBy(bounds.Width() + 22.0, 0.0); 162 fTimeEdit = new TTimeEdit(bounds, "timeEdit", 4); 163 AddChild(fTimeEdit); 164 165 bounds = fCalendarView->Frame(); 166 bounds.OffsetBy(bounds.Width() + 22.0, 0.0); 167 168 fClock = new TAnalogClock(bounds, "analogClock"); 169 AddChild(fClock); 170 171 // clock radio buttons 172 bounds.top = fClock->Frame().bottom + 10.0; 173 BStringView *text = new BStringView(bounds, "clockSetTo", "Clock set to:"); 174 AddChild(text); 175 text->ResizeToPreferred(); 176 177 bounds.left += 10.0f; 178 bounds.top = text->Frame().bottom; 179 fLocalTime = new BRadioButton(bounds, "localTime", "Local Time", 180 new BMessage(kRTCUpdate)); 181 AddChild(fLocalTime); 182 fLocalTime->ResizeToPreferred(); 183 184 bounds.left = fLocalTime->Frame().right + 10.0; 185 fGmtTime = new BRadioButton(bounds, "greenwichMeanTime", "GMT", 186 new BMessage(kRTCUpdate)); 187 AddChild(fGmtTime); 188 fGmtTime->ResizeToPreferred(); 189 190 if (fUseGmtTime) 191 fGmtTime->SetValue(B_CONTROL_ON); 192 else 193 fLocalTime->SetValue(B_CONTROL_ON); 194 195 ResizeTo(fClock->Frame().right + 10.0, fGmtTime->Frame().bottom + 10.0); 196 } 197 198 199 void 200 DateTimeView::_ReadRTCSettings() 201 { 202 BPath path; 203 if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK) 204 return; 205 206 path.Append("RTC_time_settings"); 207 208 BEntry entry(path.Path()); 209 if (entry.Exists()) { 210 BFile file(&entry, B_READ_ONLY); 211 if (file.InitCheck() == B_OK) { 212 char buffer[6]; 213 file.Read(buffer, 6); 214 if (strncmp(buffer, "gmt", 3) == 0) 215 fUseGmtTime = true; 216 } 217 } else 218 _UpdateGmtSettings(); 219 } 220 221 222 void 223 DateTimeView::_WriteRTCSettings() 224 { 225 BPath path; 226 if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK) 227 return; 228 229 path.Append("RTC_time_settings"); 230 231 BFile file(path.Path(), B_CREATE_FILE | B_ERASE_FILE | B_WRITE_ONLY); 232 if (file.InitCheck() == B_OK) { 233 if (fUseGmtTime) 234 file.Write("gmt", 3); 235 else 236 file.Write("local", 5); 237 } 238 } 239 240 241 void 242 DateTimeView::_UpdateGmtSettings() 243 { 244 _WriteRTCSettings(); 245 246 BPath path; 247 if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK) 248 return; 249 250 path.Append("timezone"); 251 BEntry entry(path.Path(), true); 252 253 if (!entry.Exists()) 254 return; 255 256 entry.GetPath(&path); 257 258 // take the existing timezone and set it's gmt use 259 _kern_set_tzfilename(path.Path(), B_PATH_NAME_LENGTH, fUseGmtTime); 260 } 261 262 263 void 264 DateTimeView::_UpdateDateTime(BMessage *message) 265 { 266 int32 day; 267 int32 month; 268 int32 year; 269 if (message->FindInt32("month", &month) == B_OK 270 && message->FindInt32("day", &day) == B_OK 271 && message->FindInt32("year", &year) == B_OK) 272 { 273 fDateEdit->SetDate(year, month, day); 274 fCalendarView->SetDate(year, month, day); 275 } 276 277 int32 hour; 278 int32 minute; 279 int32 second; 280 if (message->FindInt32("hour", &hour) == B_OK 281 && message->FindInt32("minute", &minute) == B_OK 282 && message->FindInt32("second", &second) == B_OK) 283 { 284 fClock->SetTime(hour, minute, second); 285 fTimeEdit->SetTime(hour, minute, second); 286 } 287 } 288