vfs: check userland buffers before reading them.
[haiku.git] / src / preferences / notifications / PrefletWin.cpp
blob7f75b79b9df0c06171df97db83c5927789a90622
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.
6 * Authors:
7 * Pier Luigi Fiorini, pierluigi.fiorini@gmail.com
8 * Brian Hill, supernova@tycho.email
9 */
11 #include "PrefletWin.h"
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>
22 #include <notification/Notifications.h>
24 #include "NotificationsConstants.h"
25 #include "PrefletView.h"
28 #undef B_TRANSLATION_CONTEXT
29 #define B_TRANSLATION_CONTEXT "PrefletWin"
31 const BString kSampleMessageID("NotificationsSample");
34 PrefletWin::PrefletWin()
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)
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));
46 // Defaults button
47 fDefaults = new BButton("defaults", B_TRANSLATE("Defaults"),
48 new BMessage(kDefaults));
49 fDefaults->SetEnabled(false);
51 // Revert button
52 fRevert = new BButton("revert", B_TRANSLATE("Revert"),
53 new BMessage(kRevert));
54 fRevert->SetEnabled(false);
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();
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));
75 ReloadSettings();
77 // Center this window on screen and show it
78 CenterOnScreen();
79 Show();
83 void
84 PrefletWin::MessageReceived(BMessage* msg)
86 switch (msg->what) {
87 case kApply:
88 case kApplyWithExample:
90 BPath path;
92 status_t ret = B_OK;
93 ret = find_directory(B_USER_SETTINGS_DIRECTORY, &path);
94 if (ret != B_OK)
95 return;
97 path.Append(kSettingsFile);
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;
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();
125 file.Unset();
127 if (msg->what == kApplyWithExample)
128 _SendExampleNotification();
130 break;
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;
147 default:
148 BWindow::MessageReceived(msg);
153 bool
154 PrefletWin::QuitRequested()
156 be_app_messenger.SendMessage(B_QUIT_REQUESTED);
157 return true;
161 void
162 PrefletWin::SettingChanged(bool showExample)
164 if (showExample)
165 PostMessage(kApplyWithExample);
166 else
167 PostMessage(kApply);
171 void
172 PrefletWin::ReloadSettings()
174 BPath path;
176 if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK)
177 return;
179 // FIXME don't load this again here, share with other tabs!
180 path.Append(kSettingsFile);
182 BMessage settings;
183 BFile file(path.Path(), B_READ_ONLY);
184 settings.Unflatten(&file);
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);
193 fDefaults->SetEnabled(_DefaultsPossible());
197 status_t
198 PrefletWin::_Revert()
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();
207 return B_OK;
211 bool
212 PrefletWin::_RevertPossible()
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;
221 return false;
225 status_t
226 PrefletWin::_Defaults()
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();
235 return B_OK;
239 bool
240 PrefletWin::_DefaultsPossible()
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;
249 return false;
253 void
254 PrefletWin::_SendExampleNotification()
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();