xref: /haiku/src/preferences/time/ClockView.cpp (revision 00c90992ff6fb68f75796c55942486f00fa1a37f)
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 
28 static const char* kDeskbarSignature = "application/x-vnd.Be-TSKB";
29 
30 
31 #undef B_TRANSLATION_CONTEXT
32 #define B_TRANSLATION_CONTEXT "Time"
33 
34 
35 ClockView::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_DEFAULT_SPACING);
71 }
72 
73 
74 ClockView::~ClockView()
75 {
76 }
77 
78 
79 void
80 ClockView::AttachedToWindow()
81 {
82 	if (Parent())
83 		SetViewColor(Parent()->ViewColor());
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 
106 void
107 ClockView::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 
194 bool
195 ClockView::CheckCanRevert()
196 {
197 	return fShowClock->Value() != fCachedShowClock
198 		|| fShowSeconds->Value() != fCachedShowSeconds
199 		|| fShowDayOfWeek->Value() != fCachedShowDayOfWeek
200 		|| fShowTimeZone->Value() != fCachedShowTimeZone;
201 }
202 
203 
204 void
205 ClockView::_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