1/*
2 * Copyright 2004-2011, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		John Scipione <jscipione@gmail.com>
7 */
8
9
10#include "ClockView.h"
11
12#include <Alignment.h>
13#include <Box.h>
14#include <Catalog.h>
15#include <CheckBox.h>
16#include <ControlLook.h>
17#include <LayoutBuilder.h>
18#include <Locale.h>
19#include <Message.h>
20#include <Messenger.h>
21#include <RadioButton.h>
22#include <SpaceLayoutItem.h>
23#include <Window.h>
24
25#include "TimeMessages.h"
26
27
28static const char* kDeskbarSignature = "application/x-vnd.Be-TSKB";
29
30
31#undef B_TRANSLATION_CONTEXT
32#define B_TRANSLATION_CONTEXT "Time"
33
34
35ClockView::ClockView(const char* name)
36	:
37	BView(name, 0),
38	fCachedShowClock(B_CONTROL_ON),
39	fCachedShowSeconds(B_CONTROL_OFF),
40	fCachedShowDayOfWeek(B_CONTROL_OFF),
41	fCachedShowTimeZone(B_CONTROL_OFF)
42{
43	fShowClock = new BCheckBox(B_TRANSLATE("Show clock in Deskbar"),
44		new BMessage(kShowHideTime));
45	fShowSeconds = new BCheckBox(B_TRANSLATE("Display time with seconds"),
46		new BMessage(kShowSeconds));
47	fShowDayOfWeek = new BCheckBox(B_TRANSLATE("Show day of week"),
48		new BMessage(kShowDayOfWeek));
49	fShowTimeZone = new BCheckBox(B_TRANSLATE("Show time zone"),
50		new BMessage(kShowTimeZone));
51
52	BView* view = BLayoutBuilder::Group<>(B_VERTICAL, 0)
53		.SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET))
54		.Add(fShowSeconds)
55		.Add(fShowDayOfWeek)
56		.Add(fShowTimeZone)
57		.AddGlue()
58		.SetInsets(B_USE_DEFAULT_SPACING)
59		.View();
60
61	BBox* showClockBox = new BBox("show clock box");
62	showClockBox->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, B_ALIGN_TOP));
63	showClockBox->SetLabel(fShowClock);
64	showClockBox->AddChild(view);
65
66	BLayoutBuilder::Group<>(this)
67		.AddGroup(B_VERTICAL, 0)
68			.Add(showClockBox)
69		.End()
70		.SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING,
71			B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING);
72}
73
74
75ClockView::~ClockView()
76{
77}
78
79
80void
81ClockView::AttachedToWindow()
82{
83	AdoptParentColors();
84
85	fShowClock->SetTarget(this);
86	fShowSeconds->SetTarget(this);
87	fShowDayOfWeek->SetTarget(this);
88	fShowTimeZone->SetTarget(this);
89
90	// Disable these controls initially, they'll be enabled
91	// when we get a response from Deskbar.
92	fShowClock->SetEnabled(false);
93	fShowSeconds->SetEnabled(false);
94	fShowDayOfWeek->SetEnabled(false);
95	fShowTimeZone->SetEnabled(false);
96
97	// Ask Deskbar for current clock settings, it will reply
98	// asynchronously in MesssageReceived() below.
99	BMessenger* messenger = new BMessenger(kDeskbarSignature);
100	BMessenger replyMessenger(this);
101	BMessage* message = new BMessage(kGetClockSettings);
102	messenger->SendMessage(message, replyMessenger);
103}
104
105
106void
107ClockView::MessageReceived(BMessage* message)
108{
109	switch (message->what) {
110		case kGetClockSettings:
111		{
112			// Get current clock settings from Deskbar
113			bool showClock;
114			bool showSeconds;
115			bool showDayOfWeek;
116			bool showTimeZone;
117
118			if (message->FindBool("showSeconds", &showSeconds) == B_OK) {
119				fCachedShowSeconds = showSeconds
120					? B_CONTROL_ON : B_CONTROL_OFF;
121				fShowSeconds->SetValue(fCachedShowSeconds);
122				fShowSeconds->SetEnabled(true);
123			}
124
125			if (message->FindBool("showDayOfWeek", &showDayOfWeek) == B_OK) {
126				fCachedShowDayOfWeek = showDayOfWeek
127					? B_CONTROL_ON : B_CONTROL_OFF;
128				fShowDayOfWeek->SetValue(fCachedShowDayOfWeek);
129				fShowDayOfWeek->SetEnabled(true);
130			}
131
132			if (message->FindBool("showTimeZone", &showTimeZone) == B_OK) {
133				fCachedShowTimeZone = showTimeZone
134					? B_CONTROL_ON : B_CONTROL_OFF;
135				fShowTimeZone->SetValue(fCachedShowTimeZone);
136				fShowTimeZone->SetEnabled(true);
137			}
138
139			// do this one last because it might disable the others
140			if (message->FindBool("showClock", &showClock) == B_OK) {
141				fCachedShowClock = showClock ? B_CONTROL_ON : B_CONTROL_OFF;
142				fShowClock->SetValue(fCachedShowClock);
143				fShowClock->SetEnabled(true);
144				fShowSeconds->SetEnabled(showClock);
145				fShowDayOfWeek->SetEnabled(showClock);
146				fShowTimeZone->SetEnabled(showClock);
147			}
148			break;
149		}
150
151		case kShowHideTime:
152		{
153			bool showClock;
154			if (message->FindBool("showClock", &showClock) == B_OK) {
155				// message originated from Deskbar, handle special
156				fShowClock->SetValue(showClock ? B_CONTROL_ON : B_CONTROL_OFF);
157				fShowSeconds->SetEnabled(showClock);
158				fShowDayOfWeek->SetEnabled(showClock);
159				fShowTimeZone->SetEnabled(showClock);
160
161				Window()->PostMessage(kMsgChange);
162				break;
163					// don't fall through
164			}
165			showClock = fShowClock->Value() == B_CONTROL_ON;
166			fShowSeconds->SetEnabled(showClock);
167			fShowDayOfWeek->SetEnabled(showClock);
168			fShowTimeZone->SetEnabled(showClock);
169		}
170		// fall-through
171		case kShowSeconds:
172		case kShowDayOfWeek:
173		case kShowTimeZone:
174		{
175			BMessenger* messenger = new BMessenger(kDeskbarSignature);
176			messenger->SendMessage(message);
177
178			Window()->PostMessage(kMsgChange);
179
180			break;
181		}
182
183		case kMsgRevert:
184			_Revert();
185			break;
186
187		default:
188			BView::MessageReceived(message);
189			break;
190	}
191}
192
193
194bool
195ClockView::CheckCanRevert()
196{
197	return fShowClock->Value() != fCachedShowClock
198		|| fShowSeconds->Value() != fCachedShowSeconds
199		|| fShowDayOfWeek->Value() != fCachedShowDayOfWeek
200		|| fShowTimeZone->Value() != fCachedShowTimeZone;
201}
202
203
204void
205ClockView::_Revert()
206{
207	if (fShowClock->Value() != fCachedShowClock) {
208		fShowClock->SetValue(fCachedShowClock);
209		fShowClock->Invoke();
210	}
211
212	if (fShowSeconds->Value() != fCachedShowSeconds) {
213		fShowSeconds->SetValue(fCachedShowSeconds);
214		fShowSeconds->Invoke();
215	}
216
217	if (fShowDayOfWeek->Value() != fCachedShowDayOfWeek) {
218		fShowDayOfWeek->SetValue(fCachedShowDayOfWeek);
219		fShowDayOfWeek->Invoke();
220	}
221
222	if (fShowTimeZone->Value() != fCachedShowTimeZone) {
223		fShowTimeZone->SetValue(fCachedShowTimeZone);
224		fShowTimeZone->Invoke();
225	}
226}
227