vfs: check userland buffers before reading them.
[haiku.git] / src / apps / mediaplayer / settings / SettingsWindow.cpp
blob42f46a2f6f65ca85d12b5ea511120f431375f42e
1 /*
2 * Copyright 2008-2011, Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Fredrik Modéen <fredrik@modeen.se>
7 * Stephan Aßmus <superstippi@gmx.de>
8 */
11 #include "SettingsWindow.h"
13 #include <stdio.h>
15 #include <Box.h>
16 #include <Button.h>
17 #include <Catalog.h>
18 #include <CheckBox.h>
19 #include <ControlLook.h>
20 #include <LayoutBuilder.h>
21 #include <Locale.h>
22 #include <OptionPopUp.h>
23 #include <SpaceLayoutItem.h>
24 #include <String.h>
25 #include <StringView.h>
26 #include <RadioButton.h>
27 #include <View.h>
30 #undef B_TRANSLATION_CONTEXT
31 #define B_TRANSLATION_CONTEXT "MediaPlayer-SettingsWindow"
34 enum {
35 M_SETTINGS_CHANGED = 0x3000,
37 M_SETTINGS_SAVE,
38 M_SETTINGS_CANCEL,
39 M_SETTINGS_REVERT
43 SettingsWindow::SettingsWindow(BRect frame)
45 BWindow(frame, B_TRANSLATE("MediaPlayer settings"), B_FLOATING_WINDOW_LOOK,
46 B_FLOATING_ALL_WINDOW_FEEL,
47 B_ASYNCHRONOUS_CONTROLS | B_NOT_ZOOMABLE | B_NOT_RESIZABLE
48 | B_AUTO_UPDATE_SIZE_LIMITS)
50 const float kSpacing = be_control_look->DefaultItemSpacing();
52 BBox* settingsBox = new BBox(B_PLAIN_BORDER, NULL);
53 BGroupLayout* settingsLayout = new BGroupLayout(B_VERTICAL, kSpacing / 2);
54 settingsBox->SetLayout(settingsLayout);
55 BBox* buttonBox = new BBox(B_PLAIN_BORDER, NULL);
56 BGroupLayout* buttonLayout = new BGroupLayout(B_HORIZONTAL, kSpacing / 2);
57 buttonBox->SetLayout(buttonLayout);
59 BStringView* playModeLabel = new BStringView("stringViewPlayMode",
60 B_TRANSLATE("Play mode"));
61 BStringView* viewOptionsLabel = new BStringView("stringViewViewOpions",
62 B_TRANSLATE("View options"));
63 BStringView* bgMoviesModeLabel = new BStringView("stringViewPlayBackg",
64 B_TRANSLATE("Volume of background clips"));
65 BAlignment alignment(B_ALIGN_LEFT, B_ALIGN_VERTICAL_CENTER);
66 playModeLabel->SetExplicitAlignment(alignment);
67 playModeLabel->SetFont(be_bold_font);
68 viewOptionsLabel->SetExplicitAlignment(alignment);
69 viewOptionsLabel->SetFont(be_bold_font);
70 bgMoviesModeLabel->SetExplicitAlignment(alignment);
71 bgMoviesModeLabel->SetFont(be_bold_font);
73 fAutostartCB = new BCheckBox("chkboxAutostart",
74 B_TRANSLATE("Automatically start playing"),
75 new BMessage(M_SETTINGS_CHANGED));
77 fCloseWindowMoviesCB = new BCheckBox("chkBoxCloseWindowMovies",
78 B_TRANSLATE("Close window after playing video"),
79 new BMessage(M_SETTINGS_CHANGED));
80 fCloseWindowSoundsCB = new BCheckBox("chkBoxCloseWindowSounds",
81 B_TRANSLATE("Close window after playing audio"),
82 new BMessage(M_SETTINGS_CHANGED));
84 fLoopMoviesCB = new BCheckBox("chkBoxLoopMovie",
85 B_TRANSLATE("Loop video"),
86 new BMessage(M_SETTINGS_CHANGED));
87 fLoopSoundsCB = new BCheckBox("chkBoxLoopSounds",
88 B_TRANSLATE("Loop audio"),
89 new BMessage(M_SETTINGS_CHANGED));
91 fUseOverlaysCB = new BCheckBox("chkBoxUseOverlays",
92 B_TRANSLATE("Use hardware video overlays if available"),
93 new BMessage(M_SETTINGS_CHANGED));
94 fScaleBilinearCB = new BCheckBox("chkBoxScaleBilinear",
95 B_TRANSLATE("Scale movies smoothly (non-overlay mode)"),
96 new BMessage(M_SETTINGS_CHANGED));
98 fScaleFullscreenControlsCB = new BCheckBox("chkBoxScaleControls",
99 B_TRANSLATE("Scale controls in full screen mode"),
100 new BMessage(M_SETTINGS_CHANGED));
102 fSubtitleSizeOP = new BOptionPopUp("subtitleSize",
103 B_TRANSLATE("Subtitle size:"), new BMessage(M_SETTINGS_CHANGED));
104 fSubtitleSizeOP->AddOption(
105 B_TRANSLATE("Small"), mpSettings::SUBTITLE_SIZE_SMALL);
106 fSubtitleSizeOP->AddOption(
107 B_TRANSLATE("Medium"), mpSettings::SUBTITLE_SIZE_MEDIUM);
108 fSubtitleSizeOP->AddOption(
109 B_TRANSLATE("Large"), mpSettings::SUBTITLE_SIZE_LARGE);
111 fSubtitlePlacementOP = new BOptionPopUp("subtitlePlacement",
112 B_TRANSLATE("Subtitle placement:"), new BMessage(M_SETTINGS_CHANGED));
113 fSubtitlePlacementOP->AddOption(B_TRANSLATE("Bottom of video"),
114 mpSettings::SUBTITLE_PLACEMENT_BOTTOM_OF_VIDEO);
115 fSubtitlePlacementOP->AddOption(B_TRANSLATE("Bottom of screen"),
116 mpSettings::SUBTITLE_PLACEMENT_BOTTOM_OF_SCREEN);
118 fFullVolumeBGMoviesRB = new BRadioButton("rdbtnfullvolume",
119 B_TRANSLATE("Full volume"), new BMessage(M_SETTINGS_CHANGED));
121 fHalfVolumeBGMoviesRB = new BRadioButton("rdbtnhalfvolume",
122 B_TRANSLATE("Low volume"), new BMessage(M_SETTINGS_CHANGED));
124 fMutedVolumeBGMoviesRB = new BRadioButton("rdbtnfullvolume",
125 B_TRANSLATE("Muted"), new BMessage(M_SETTINGS_CHANGED));
127 fRevertB = new BButton("revert", B_TRANSLATE("Revert"),
128 new BMessage(M_SETTINGS_REVERT));
130 BButton* cancelButton = new BButton("cancel", B_TRANSLATE("Cancel"),
131 new BMessage(M_SETTINGS_CANCEL));
133 BButton* okButton = new BButton("ok", B_TRANSLATE("OK"),
134 new BMessage(M_SETTINGS_SAVE));
135 okButton->MakeDefault(true);
137 // Build the layout
138 BGroupLayout* volumeGroup;
139 BGroupLayout* startGroup;
140 BGroupLayout* playGroup;
141 BLayoutBuilder::Group<>(this, B_VERTICAL, 0)
142 .AddGroup(settingsLayout)
143 .SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING,
144 B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING)
145 .Add(playModeLabel)
146 .AddGroup(B_HORIZONTAL, 0)
147 .GetLayout(&playGroup)
148 .AddStrut(10)
149 .AddGroup(B_VERTICAL, 0)
150 .GetLayout(&startGroup)
151 .Add(fAutostartCB)
152 .AddGrid(kSpacing, 0)
153 .Add(BSpaceLayoutItem::CreateHorizontalStrut(kSpacing), 0, 0)
154 .Add(fCloseWindowMoviesCB, 1, 0)
155 .Add(BSpaceLayoutItem::CreateHorizontalStrut(kSpacing), 0, 1)
156 .Add(fCloseWindowSoundsCB, 1, 1)
157 .End()
158 .Add(fLoopMoviesCB)
159 .Add(fLoopSoundsCB)
160 .End()
161 .End()
162 .AddStrut(kSpacing)
164 .Add(viewOptionsLabel)
165 .AddGroup(B_HORIZONTAL, 0)
166 .AddStrut(10)
167 .AddGroup(B_VERTICAL, 0)
168 .Add(fUseOverlaysCB)
169 .Add(fScaleBilinearCB)
170 .Add(fScaleFullscreenControlsCB)
171 .Add(fSubtitleSizeOP)
172 .Add(fSubtitlePlacementOP)
173 .End()
174 .End()
175 .AddStrut(kSpacing)
177 .Add(bgMoviesModeLabel)
178 .AddGroup(B_HORIZONTAL, 0)
179 .AddStrut(10)
180 .AddGroup(B_VERTICAL, 0)
181 .GetLayout(&volumeGroup)
182 .Add(fFullVolumeBGMoviesRB)
183 .Add(fHalfVolumeBGMoviesRB)
184 .Add(fMutedVolumeBGMoviesRB)
185 .End()
186 .End()
187 .AddStrut(kSpacing)
188 .End()
189 .AddGroup(buttonLayout)
190 .SetInsets(B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING,
191 B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING)
192 .Add(fRevertB)
193 .AddGlue()
194 .Add(cancelButton)
195 .Add(okButton);
197 startGroup->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));
198 playGroup->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));
199 volumeGroup->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));
203 SettingsWindow::~SettingsWindow()
208 void
209 SettingsWindow::Show()
211 // The Settings that we want to be able to revert to is the state at which
212 // the SettingsWindow was shown. So the current settings are stored in
213 // fLastSettings.
214 Settings::Default()->Get(fLastSettings);
215 fSettings = fLastSettings;
216 AdoptSettings();
218 BWindow::Show();
222 bool
223 SettingsWindow::QuitRequested()
225 Hide();
226 return false;
230 void
231 SettingsWindow::MessageReceived(BMessage* message)
233 switch (message->what) {
234 case M_SETTINGS_CHANGED:
235 ApplySettings();
236 break;
238 case B_KEY_DOWN:
239 int32 index;
240 if (message->FindInt32("key", &index) == B_OK && index == 1)
241 PostMessage(B_QUIT_REQUESTED);
242 break;
244 case M_SETTINGS_REVERT:
245 Revert();
246 break;
248 case M_SETTINGS_CANCEL:
249 Revert();
250 // fall through
251 case M_SETTINGS_SAVE:
252 PostMessage(B_QUIT_REQUESTED);
253 break;
255 default:
256 BWindow::MessageReceived(message);
257 break;
262 void
263 SettingsWindow::AdoptSettings()
265 fAutostartCB->SetValue(fSettings.autostart);
266 fCloseWindowMoviesCB->SetValue(fSettings.closeWhenDonePlayingMovie);
267 fCloseWindowSoundsCB->SetValue(fSettings.closeWhenDonePlayingSound);
268 fLoopMoviesCB->SetValue(fSettings.loopMovie);
269 fLoopSoundsCB->SetValue(fSettings.loopSound);
271 fUseOverlaysCB->SetValue(fSettings.useOverlays);
272 fScaleBilinearCB->SetValue(fSettings.scaleBilinear);
273 fScaleFullscreenControlsCB->SetValue(fSettings.scaleFullscreenControls);
275 fSubtitleSizeOP->SetValue(fSettings.subtitleSize);
276 fSubtitlePlacementOP->SetValue(fSettings.subtitlePlacement);
278 fFullVolumeBGMoviesRB->SetValue(fSettings.backgroundMovieVolumeMode
279 == mpSettings::BG_MOVIES_FULL_VOLUME);
280 fHalfVolumeBGMoviesRB->SetValue(fSettings.backgroundMovieVolumeMode
281 == mpSettings::BG_MOVIES_HALF_VLUME);
282 fMutedVolumeBGMoviesRB->SetValue(fSettings.backgroundMovieVolumeMode
283 == mpSettings::BG_MOVIES_MUTED);
285 fRevertB->SetEnabled(IsRevertable());
289 void
290 SettingsWindow::ApplySettings()
292 fSettings.autostart = fAutostartCB->Value() == B_CONTROL_ON;
293 fSettings.closeWhenDonePlayingMovie
294 = fCloseWindowMoviesCB->Value() == B_CONTROL_ON;
295 fSettings.closeWhenDonePlayingSound
296 = fCloseWindowSoundsCB->Value() == B_CONTROL_ON;
297 fSettings.loopMovie = fLoopMoviesCB->Value() == B_CONTROL_ON;
298 fSettings.loopSound = fLoopSoundsCB->Value() == B_CONTROL_ON;
300 fSettings.useOverlays = fUseOverlaysCB->Value() == B_CONTROL_ON;
301 fSettings.scaleBilinear = fScaleBilinearCB->Value() == B_CONTROL_ON;
302 fSettings.scaleFullscreenControls
303 = fScaleFullscreenControlsCB->Value() == B_CONTROL_ON;
305 fSettings.subtitleSize = fSubtitleSizeOP->Value();
306 fSettings.subtitlePlacement = fSubtitlePlacementOP->Value();
308 if (fFullVolumeBGMoviesRB->Value() == B_CONTROL_ON) {
309 fSettings.backgroundMovieVolumeMode
310 = mpSettings::BG_MOVIES_FULL_VOLUME;
311 } else if (fHalfVolumeBGMoviesRB->Value() == B_CONTROL_ON) {
312 fSettings.backgroundMovieVolumeMode
313 = mpSettings::BG_MOVIES_HALF_VLUME;
314 } else if (fMutedVolumeBGMoviesRB->Value() == B_CONTROL_ON) {
315 fSettings.backgroundMovieVolumeMode
316 = mpSettings::BG_MOVIES_MUTED;
319 Settings::Default()->Update(fSettings);
321 fRevertB->SetEnabled(IsRevertable());
325 void
326 SettingsWindow::Revert()
328 fSettings = fLastSettings;
329 AdoptSettings();
330 Settings::Default()->Update(fSettings);
334 bool
335 SettingsWindow::IsRevertable() const
337 return fSettings != fLastSettings;