xref: /haiku/src/preferences/notifications/PrefletWin.cpp (revision 6aa0587222b965a635512f99861a5f6a9ad465a8)
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 "PrefletWin.h"
12 
13 #include <Alert.h>
14 #include <Application.h>
15 #include <Button.h>
16 #include <Catalog.h>
17 #include <FindDirectory.h>
18 #include <Notification.h>
19 #include <Path.h>
20 #include <SeparatorView.h>
21 
22 #include <notification/Notifications.h>
23 
24 #include "NotificationsConstants.h"
25 #include "PrefletView.h"
26 
27 
28 #undef B_TRANSLATION_CONTEXT
29 #define B_TRANSLATION_CONTEXT "PrefletWin"
30 
31 const BString kSampleMessageID("NotificationsSample");
32 
33 
PrefletWin()34 PrefletWin::PrefletWin()
35 	:
36 	BWindow(BRect(0, 0, 160 + 20 * be_plain_font->Size(), 300),
37 		B_TRANSLATE_SYSTEM_NAME("Notifications"),
38 		B_TITLED_WINDOW, B_NOT_ZOOMABLE | B_ASYNCHRONOUS_CONTROLS
39 		| B_AUTO_UPDATE_SIZE_LIMITS)
40 {
41 	// Preflet container view
42 	fMainView = new PrefletView(this);
43 	fMainView->SetBorder(B_NO_BORDER);
44 	fMainView->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED));
45 
46 	// Defaults button
47 	fDefaults = new BButton("defaults", B_TRANSLATE("Defaults"),
48 		new BMessage(kDefaults));
49 	fDefaults->SetEnabled(false);
50 
51 	// Revert button
52 	fRevert = new BButton("revert", B_TRANSLATE("Revert"),
53 		new BMessage(kRevert));
54 	fRevert->SetEnabled(false);
55 
56 	// Build the layout
57 	fButtonsView = new BGroupView();
58 	BLayoutBuilder::Group<>(fButtonsView, B_VERTICAL, 0)
59 		.AddGroup(B_HORIZONTAL)
60 			.Add(fDefaults)
61 			.Add(fRevert)
62 			.AddGlue()
63 			.SetInsets(B_USE_WINDOW_SPACING, 0, B_USE_WINDOW_SPACING,
64 				B_USE_WINDOW_SPACING)
65 		.End();
66 	fButtonsLayout = fButtonsView->GroupLayout();
67 
68 	BLayoutBuilder::Group<>(this, B_VERTICAL, 0)
69 		.SetInsets(0, B_USE_DEFAULT_SPACING, 0, 0)
70 		.Add(fMainView)
71 		.Add(fButtonsView)
72 	.End();
73 	fMainView->SetExplicitMinSize(BSize(Frame().Width(), B_SIZE_UNSET));
74 
75 	ReloadSettings();
76 
77 	// Center this window on screen and show it
78 	CenterOnScreen();
79 	Show();
80 }
81 
82 
83 void
MessageReceived(BMessage * msg)84 PrefletWin::MessageReceived(BMessage* msg)
85 {
86 	switch (msg->what) {
87 		case kApply:
88 		case kApplyWithExample:
89 		{
90 			BPath path;
91 
92 			status_t ret = B_OK;
93 			ret = find_directory(B_USER_SETTINGS_DIRECTORY, &path);
94 			if (ret != B_OK)
95 				return;
96 
97 			path.Append(kSettingsFile);
98 
99 			BMessage settingsStore;
100 			int32 count = fMainView->CountTabs();
101 			for (int32 i = 0; i < count; i++) {
102 				SettingsPane* pane =
103 					dynamic_cast<SettingsPane*>(fMainView->PageAt(i));
104 				if (pane) {
105 					if (pane->Save(settingsStore) == B_OK) {
106 						fDefaults->SetEnabled(_DefaultsPossible());
107 						fRevert->SetEnabled(_RevertPossible());
108 					} else
109 						break;
110 				}
111 			}
112 
113 			// Save settings file
114 			BFile file(path.Path(), B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE);
115 			ret = settingsStore.Flatten(&file);
116 			if (ret != B_OK) {
117 				BAlert* alert = new BAlert("",
118 					B_TRANSLATE("An error occurred saving the preferences.\n"
119 						"It's possible you are running out of disk space."),
120 					B_TRANSLATE("OK"), NULL, NULL, B_WIDTH_AS_USUAL,
121 					B_STOP_ALERT);
122 				alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
123 				(void)alert->Go();
124 			}
125 			file.Unset();
126 
127 			if (msg->what == kApplyWithExample)
128 				_SendExampleNotification();
129 
130 			break;
131 		}
132 		case kDefaults:
133 			fDefaults->SetEnabled(false);
134 			_Defaults();
135 			PostMessage(kApply);
136 			break;
137 		case kRevert:
138 			fRevert->SetEnabled(false);
139 			_Revert();
140 			PostMessage(kApply);
141 			break;
142 		case kShowButtons: {
143 			bool show = msg->GetBool(kShowButtonsKey, true);
144 			fButtonsLayout->SetVisible(show);
145 			break;
146 		}
147 		default:
148 			BWindow::MessageReceived(msg);
149 	}
150 }
151 
152 
153 bool
QuitRequested()154 PrefletWin::QuitRequested()
155 {
156 	be_app_messenger.SendMessage(B_QUIT_REQUESTED);
157 	return true;
158 }
159 
160 
161 void
SettingChanged(bool showExample)162 PrefletWin::SettingChanged(bool showExample)
163 {
164 	if (showExample)
165 		PostMessage(kApplyWithExample);
166 	else
167 		PostMessage(kApply);
168 }
169 
170 
171 void
ReloadSettings()172 PrefletWin::ReloadSettings()
173 {
174 	BPath path;
175 
176 	if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK)
177 		return;
178 
179 	// FIXME don't load this again here, share with other tabs!
180 	path.Append(kSettingsFile);
181 
182 	BMessage settings;
183 	BFile file(path.Path(), B_READ_ONLY);
184 	settings.Unflatten(&file);
185 
186 	int32 count = fMainView->CountTabs();
187 	for (int32 i = 0; i < count; i++) {
188 		SettingsPane* pane =
189 			dynamic_cast<SettingsPane*>(fMainView->PageAt(i));
190 		if (pane)
191 			pane->Load(settings);
192 	}
193 	fDefaults->SetEnabled(_DefaultsPossible());
194 }
195 
196 
197 status_t
_Revert()198 PrefletWin::_Revert()
199 {
200 	int32 count = fMainView->CountTabs();
201 	for (int32 i = 0; i < count; i++) {
202 		SettingsPane* pane =
203 			dynamic_cast<SettingsPane*>(fMainView->PageAt(i));
204 		if (pane)
205 			pane->Revert();
206 	}
207 	return B_OK;
208 }
209 
210 
211 bool
_RevertPossible()212 PrefletWin::_RevertPossible()
213 {
214 	int32 count = fMainView->CountTabs();
215 	for (int32 i = 0; i < count; i++) {
216 		SettingsPane* pane =
217 			dynamic_cast<SettingsPane*>(fMainView->PageAt(i));
218 		if (pane && pane->RevertPossible())
219 			return true;
220 	}
221 	return false;
222 }
223 
224 
225 status_t
_Defaults()226 PrefletWin::_Defaults()
227 {
228 	int32 count = fMainView->CountTabs();
229 	for (int32 i = 0; i < count; i++) {
230 		SettingsPane* pane =
231 			dynamic_cast<SettingsPane*>(fMainView->PageAt(i));
232 		if (pane)
233 			pane->Defaults();
234 	}
235 	return B_OK;
236 }
237 
238 
239 bool
_DefaultsPossible()240 PrefletWin::_DefaultsPossible()
241 {
242 	int32 count = fMainView->CountTabs();
243 	for (int32 i = 0; i < count; i++) {
244 		SettingsPane* pane =
245 			dynamic_cast<SettingsPane*>(fMainView->PageAt(i));
246 		if (pane && pane->DefaultsPossible())
247 			return true;
248 	}
249 	return false;
250 }
251 
252 
253 void
_SendExampleNotification()254 PrefletWin::_SendExampleNotification()
255 {
256 	BNotification notification(B_INFORMATION_NOTIFICATION);
257 	notification.SetMessageID(kSampleMessageID);
258 	notification.SetGroup(B_TRANSLATE("Notifications"));
259 	notification.SetTitle(B_TRANSLATE("Notifications preflet sample"));
260 	notification.SetContent(B_TRANSLATE("This is a test notification message"));
261 	notification.Send();
262 }
263