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