xref: /haiku/src/preferences/notifications/GeneralView.cpp (revision 6aff37d1c79e20748c683ae224bd629f88a5b0be)
1 /*
2  * Copyright 2010-2017, Haiku, Inc. All Rights Reserved.
3  * Copyright 2009, Pier Luigi Fiorini.
4  * Distributed under the terms of the MIT License.
5  *
6  * Authors:
7  *		Pier Luigi Fiorini, pierluigi.fiorini@gmail.com
8  *		Brian Hill, supernova@tycho.email
9  */
10 
11 #include <stdio.h>
12 #include <stdlib.h>
13 
14 #include <vector>
15 
16 #include <Alert.h>
17 #include <Box.h>
18 #include <Button.h>
19 #include <Catalog.h>
20 #include <Directory.h>
21 #include <File.h>
22 #include <FindDirectory.h>
23 #include <Font.h>
24 #include <LayoutBuilder.h>
25 #include <Node.h>
26 #include <Path.h>
27 #include <Query.h>
28 #include <Roster.h>
29 #include <String.h>
30 #include <SymLink.h>
31 #include <Volume.h>
32 #include <VolumeRoster.h>
33 
34 #include <notification/Notifications.h>
35 
36 #include "GeneralView.h"
37 #include "NotificationsConstants.h"
38 #include "SettingsHost.h"
39 
40 #undef B_TRANSLATION_CONTEXT
41 #define B_TRANSLATION_CONTEXT "GeneralView"
42 
43 const uint32 kToggleNotifications = '_TSR';
44 const uint32 kWidthChanged = '_WIC';
45 const uint32 kTimeoutChanged = '_TIC';
46 const uint32 kServerChangeTriggered = '_SCT';
47 const BString kSampleMessageID("NotificationsSample");
48 
49 
50 GeneralView::GeneralView(SettingsHost* host)
51 	:
52 	SettingsPane("general", host)
53 {
54 	// Notification server
55 	fNotificationBox = new BCheckBox("server",
56 		B_TRANSLATE("Enable notifications"),
57 		new BMessage(kToggleNotifications));
58 	BBox* box = new BBox("box");
59 	box->SetLabel(fNotificationBox);
60 
61 	// Window width
62 	int32 minWidth = int32(kMinimumWidth / kWidthStep);
63 	int32 maxWidth = int32(kMaximumWidth / kWidthStep);
64 	fWidthSlider = new BSlider("width", B_TRANSLATE("Window width:"),
65 		new BMessage(kWidthChanged), minWidth, maxWidth, B_HORIZONTAL);
66 	fWidthSlider->SetHashMarks(B_HASH_MARKS_BOTTOM);
67 	fWidthSlider->SetHashMarkCount(maxWidth - minWidth + 1);
68 	BString minWidthLabel;
69 	minWidthLabel << int32(kMinimumWidth);
70 	BString maxWidthLabel;
71 	maxWidthLabel << int32(kMaximumWidth);
72 	fWidthSlider->SetLimitLabels(
73 		B_TRANSLATE_COMMENT(minWidthLabel.String(), "Slider low text"),
74 		B_TRANSLATE_COMMENT(maxWidthLabel.String(), "Slider high text"));
75 
76 	// Display time
77 	fDurationSlider = new BSlider("duration", B_TRANSLATE("Duration:"),
78 		new BMessage(kTimeoutChanged), kMinimumTimeout, kMaximumTimeout,
79 		B_HORIZONTAL);
80 	fDurationSlider->SetHashMarks(B_HASH_MARKS_BOTTOM);
81 	fDurationSlider->SetHashMarkCount(kMaximumTimeout - kMinimumTimeout + 1);
82 	BString minLabel;
83 	minLabel << kMinimumTimeout;
84 	BString maxLabel;
85 	maxLabel << kMaximumTimeout;
86 	fDurationSlider->SetLimitLabels(
87 		B_TRANSLATE_COMMENT(minLabel.String(), "Slider low text"),
88 		B_TRANSLATE_COMMENT(maxLabel.String(), "Slider high text"));
89 
90 	box->AddChild(BLayoutBuilder::Group<>(B_VERTICAL)
91 		.SetInsets(B_USE_DEFAULT_SPACING)
92 		.Add(fWidthSlider)
93 		.Add(fDurationSlider)
94 		.AddGlue()
95 		.View());
96 
97 	BLayoutBuilder::Group<>(this, B_VERTICAL)
98 		.SetInsets(B_USE_WINDOW_SPACING)
99 		.Add(box)
100 	.End();
101 }
102 
103 
104 void
105 GeneralView::AttachedToWindow()
106 {
107 	BView::AttachedToWindow();
108 	fNotificationBox->SetTarget(this);
109 	fWidthSlider->SetTarget(this);
110 	fDurationSlider->SetTarget(this);
111 }
112 
113 
114 void
115 GeneralView::MessageReceived(BMessage* msg)
116 {
117 	switch (msg->what) {
118 		case kToggleNotifications:
119 		{
120 			SettingsPane::SettingsChanged(false);
121 			_EnableControls();
122 			break;
123 		}
124 		case kWidthChanged: {
125 			int32 value = fWidthSlider->Value() * 50;
126 			_SetWidthLabel(value);
127 			SettingsPane::SettingsChanged(true);
128 			break;
129 		}
130 		case kTimeoutChanged:
131 		{
132 			int32 value = fDurationSlider->Value();
133 			_SetTimeoutLabel(value);
134 			SettingsPane::SettingsChanged(true);
135 			break;
136 		}
137 		default:
138 			BView::MessageReceived(msg);
139 			break;
140 	}
141 }
142 
143 
144 status_t
145 GeneralView::Load(BMessage& settings)
146 {
147 	bool autoStart = settings.GetBool(kAutoStartName, true);
148 	fNotificationBox->SetValue(autoStart ? B_CONTROL_ON : B_CONTROL_OFF);
149 
150 	if (settings.FindFloat(kWidthName, &fOriginalWidth) != B_OK
151 		|| fOriginalWidth > kMaximumWidth
152 		|| fOriginalWidth < kMinimumWidth)
153 		fOriginalWidth = kDefaultWidth;
154 
155 	if (settings.FindInt32(kTimeoutName, &fOriginalTimeout) != B_OK
156 		|| fOriginalTimeout > kMaximumTimeout
157 		|| fOriginalTimeout < kMinimumTimeout)
158 		fOriginalTimeout = kDefaultTimeout;
159 // TODO need to save again if values outside of expected range
160 	int32 setting;
161 	if (settings.FindInt32(kIconSizeName, &setting) != B_OK)
162 		fOriginalIconSize = kDefaultIconSize;
163 	else
164 		fOriginalIconSize = (icon_size)setting;
165 
166 	_EnableControls();
167 
168 	return Revert();
169 }
170 
171 
172 status_t
173 GeneralView::Save(BMessage& settings)
174 {
175 	bool autoStart = (fNotificationBox->Value() == B_CONTROL_ON);
176 	settings.AddBool(kAutoStartName, autoStart);
177 
178 	int32 timeout = fDurationSlider->Value();
179 	settings.AddInt32(kTimeoutName, timeout);
180 
181 	float width = fWidthSlider->Value() * 50;
182 	settings.AddFloat(kWidthName, width);
183 
184 	icon_size iconSize = B_LARGE_ICON;
185 	settings.AddInt32(kIconSizeName, (int32)iconSize);
186 
187 	return B_OK;
188 }
189 
190 
191 status_t
192 GeneralView::Revert()
193 {
194 	fDurationSlider->SetValue(fOriginalTimeout);
195 	_SetTimeoutLabel(fOriginalTimeout);
196 
197 	fWidthSlider->SetValue(fOriginalWidth / 50);
198 	_SetWidthLabel(fOriginalWidth);
199 
200 	return B_OK;
201 }
202 
203 
204 bool
205 GeneralView::RevertPossible()
206 {
207 	int32 timeout = fDurationSlider->Value();
208 	if (fOriginalTimeout != timeout)
209 		return true;
210 
211 	int32 width = fWidthSlider->Value() * 50;
212 	if (fOriginalWidth != width)
213 		return true;
214 
215 	return false;
216 }
217 
218 
219 status_t
220 GeneralView::Defaults()
221 {
222 	fDurationSlider->SetValue(kDefaultTimeout);
223 	_SetTimeoutLabel(kDefaultTimeout);
224 
225 	fWidthSlider->SetValue(kDefaultWidth / 50);
226 	_SetWidthLabel(kDefaultWidth);
227 
228 	return B_OK;
229 }
230 
231 
232 bool
233 GeneralView::DefaultsPossible()
234 {
235 	int32 timeout = fDurationSlider->Value();
236 	if (kDefaultTimeout != timeout)
237 		return true;
238 
239 	int32 width = fWidthSlider->Value() * 50;
240 	if (kDefaultWidth != width)
241 		return true;
242 
243 	return false;
244 }
245 
246 
247 bool
248 GeneralView::UseDefaultRevertButtons()
249 {
250 	return true;
251 }
252 
253 
254 void
255 GeneralView::_EnableControls()
256 {
257 	bool enabled = fNotificationBox->Value() == B_CONTROL_ON;
258 	fWidthSlider->SetEnabled(enabled);
259 	fDurationSlider->SetEnabled(enabled);
260 }
261 
262 
263 void
264 GeneralView::_SetTimeoutLabel(int32 value)
265 {
266 	BString label(B_TRANSLATE("Timeout:"));
267 	label.Append(" ");
268 	label << value;
269 	label.Append(" ").Append(B_TRANSLATE("seconds"));
270 	fDurationSlider->SetLabel(label.String());
271 }
272 
273 
274 void
275 GeneralView::_SetWidthLabel(int32 value)
276 {
277 	BString label(B_TRANSLATE("Width:"));
278 	label.Append(" ");
279 	label << value;
280 	label.Append(" ").Append(B_TRANSLATE("pixels"));
281 	fWidthSlider->SetLabel(label.String());
282 }
283 
284 
285 bool
286 GeneralView::_IsServerRunning()
287 {
288 	return be_roster->IsRunning(kNotificationServerSignature);
289 }
290