vfs: check userland buffers before reading them.
[haiku.git] / src / preferences / appearance / LookAndFeelSettingsView.cpp
blob07ae697067b2d64fe93ac99d4b5af021d92363b5
1 /*
2 * Copyright 2010-2012 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT license.
5 * Authors:
6 * Stephan Aßmus <superstippi@gmx.de>
7 * Alexander von Gluck <kallisti5@unixzen.com>
8 * John Scipione <jscipione@gmail.com>
9 * Ryan Leavengood <leavengood@gmail.com>
13 #include "LookAndFeelSettingsView.h"
15 #include <stdio.h>
16 #include <stdlib.h>
18 #include <Alert.h>
19 #include <Alignment.h>
20 #include <Box.h>
21 #include <Button.h>
22 #include <Catalog.h>
23 #include <CheckBox.h>
24 #include <InterfaceDefs.h>
25 #include <LayoutBuilder.h>
26 #include <Locale.h>
27 #include <MenuField.h>
28 #include <MenuItem.h>
29 #include <PopUpMenu.h>
30 #include <ScrollBar.h>
31 #include <StringView.h>
32 #include <Size.h>
33 #include <Slider.h>
34 #include <SpaceLayoutItem.h>
35 #include <StringView.h>
36 #include <TextView.h>
38 #include "APRWindow.h"
39 #include "FakeScrollBar.h"
42 #undef B_TRANSLATION_CONTEXT
43 #define B_TRANSLATION_CONTEXT "DecorSettingsView"
44 // This was not renamed to keep from breaking translations
47 static const int32 kMsgSetDecor = 'deco';
48 static const int32 kMsgDecorInfo = 'idec';
50 static const int32 kMsgDoubleScrollBarArrows = 'dsba';
52 static const int32 kMsgArrowStyleSingle = 'mass';
53 static const int32 kMsgArrowStyleDouble = 'masd';
55 static const int32 kMsgKnobStyleNone = 'mksn';
56 static const int32 kMsgKnobStyleDots = 'mksd';
57 static const int32 kMsgKnobStyleLines = 'mksl';
59 static const bool kDefaultDoubleScrollBarArrowsSetting = false;
62 // #pragma mark -
65 LookAndFeelSettingsView::LookAndFeelSettingsView(const char* name)
67 BView(name, 0),
68 fDecorInfoButton(NULL),
69 fDecorMenuField(NULL),
70 fDecorMenu(NULL)
72 // Decorator menu
73 _BuildDecorMenu();
74 fDecorMenuField = new BMenuField("decorator",
75 B_TRANSLATE("Decorator:"), fDecorMenu);
77 fDecorInfoButton = new BButton(B_TRANSLATE("About"),
78 new BMessage(kMsgDecorInfo));
80 // scroll bar arrow style
81 BBox* arrowStyleBox = new BBox("arrow style");
82 arrowStyleBox->SetLabel(B_TRANSLATE("Arrow style"));
84 fSavedDoubleArrowsValue = _DoubleScrollBarArrows();
86 fArrowStyleSingle = new FakeScrollBar(true, false,
87 new BMessage(kMsgArrowStyleSingle));
88 fArrowStyleDouble = new FakeScrollBar(true, true,
89 new BMessage(kMsgArrowStyleDouble));
91 BView* arrowStyleView;
92 arrowStyleView = BLayoutBuilder::Group<>()
93 .AddGroup(B_VERTICAL, 1)
94 .Add(new BStringView("single", B_TRANSLATE("Single:")))
95 .Add(fArrowStyleSingle)
96 .AddStrut(B_USE_DEFAULT_SPACING)
97 .Add(new BStringView("double", B_TRANSLATE("Double:")))
98 .Add(fArrowStyleDouble)
99 .SetInsets(B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING,
100 B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING)
101 .End()
102 .View();
103 arrowStyleBox->AddChild(arrowStyleView);
104 arrowStyleBox->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT,
105 B_ALIGN_VERTICAL_CENTER));
106 arrowStyleBox->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));
108 BStringView* scrollBarLabel
109 = new BStringView("scroll bar", B_TRANSLATE("Scroll bar:"));
110 scrollBarLabel->SetExplicitAlignment(
111 BAlignment(B_ALIGN_LEFT, B_ALIGN_TOP));
113 // control layout
114 BLayoutBuilder::Grid<>(this, B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING)
115 .Add(fDecorMenuField->CreateLabelLayoutItem(), 0, 0)
116 .Add(fDecorMenuField->CreateMenuBarLayoutItem(), 1, 0)
117 .Add(fDecorInfoButton, 2, 0)
118 .Add(scrollBarLabel, 0, 1)
119 .Add(arrowStyleBox, 1, 1)
120 .AddGlue(0, 2)
121 .SetInsets(B_USE_WINDOW_SPACING);
123 // TODO : Decorator Preview Image?
127 LookAndFeelSettingsView::~LookAndFeelSettingsView()
132 void
133 LookAndFeelSettingsView::AttachedToWindow()
135 AdoptParentColors();
137 if (Parent() == NULL)
138 SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
140 fDecorMenu->SetTargetForItems(this);
141 fDecorInfoButton->SetTarget(this);
142 fArrowStyleSingle->SetTarget(this);
143 fArrowStyleDouble->SetTarget(this);
145 if (fSavedDoubleArrowsValue)
146 fArrowStyleDouble->SetValue(B_CONTROL_ON);
147 else
148 fArrowStyleSingle->SetValue(B_CONTROL_ON);
152 void
153 LookAndFeelSettingsView::MessageReceived(BMessage *msg)
155 switch (msg->what) {
156 case kMsgSetDecor:
158 BString newDecor;
159 if (msg->FindString("decor", &newDecor) == B_OK)
160 _SetDecor(newDecor);
161 break;
164 case kMsgDecorInfo:
166 DecorInfo* decor = fDecorUtility.FindDecorator(fCurrentDecor);
167 if (decor == NULL)
168 break;
170 BString authorsText(decor->Authors().String());
171 authorsText.ReplaceAll(", ", "\n\t");
173 BString infoText(B_TRANSLATE("%decorName\n\n"
174 "Authors:\n\t%decorAuthors\n\n"
175 "URL: %decorURL\n"
176 "License: %decorLic\n\n"
177 "%decorDesc\n"));
180 infoText.ReplaceFirst("%decorName", decor->Name().String());
181 infoText.ReplaceFirst("%decorAuthors", authorsText.String());
182 infoText.ReplaceFirst("%decorLic", decor->LicenseName().String());
183 infoText.ReplaceFirst("%decorURL", decor->SupportURL().String());
184 infoText.ReplaceFirst("%decorDesc", decor->ShortDescription().String());
186 BAlert *infoAlert = new BAlert(B_TRANSLATE("About decorator"),
187 infoText.String(), B_TRANSLATE("OK"));
188 infoAlert->SetFlags(infoAlert->Flags() | B_CLOSE_ON_ESCAPE);
189 infoAlert->Go();
191 break;
194 case kMsgArrowStyleSingle:
195 _SetDoubleScrollBarArrows(false);
196 break;
198 case kMsgArrowStyleDouble:
199 _SetDoubleScrollBarArrows(true);
200 break;
202 default:
203 BView::MessageReceived(msg);
204 break;
209 void
210 LookAndFeelSettingsView::_BuildDecorMenu()
212 fDecorMenu = new BPopUpMenu(B_TRANSLATE("Choose Decorator"));
214 // collect the current system decor settings
215 int32 count = fDecorUtility.CountDecorators();
216 for (int32 i = 0; i < count; ++i) {
217 DecorInfo* decorator = fDecorUtility.DecoratorAt(i);
218 if (decorator == NULL) {
219 fprintf(stderr, "Decorator : error NULL entry @ %" B_PRId32
220 " / %" B_PRId32 "\n", i, count);
221 continue;
224 BString decorName = decorator->Name();
226 BMessage* message = new BMessage(kMsgSetDecor);
227 message->AddString("decor", decorName);
229 BMenuItem* item = new BMenuItem(decorName, message);
231 fDecorMenu->AddItem(item);
234 _AdoptToCurrentDecor();
238 void
239 LookAndFeelSettingsView::_SetDecor(const BString& name)
241 _SetDecor(fDecorUtility.FindDecorator(name));
245 void
246 LookAndFeelSettingsView::_SetDecor(DecorInfo* decorInfo)
248 if (fDecorUtility.SetDecorator(decorInfo) == B_OK) {
249 _AdoptToCurrentDecor();
250 Window()->PostMessage(kMsgUpdate);
255 void
256 LookAndFeelSettingsView::_AdoptToCurrentDecor()
258 fCurrentDecor = fDecorUtility.CurrentDecorator()->Name();
259 if (fSavedDecor.Length() == 0)
260 fSavedDecor = fCurrentDecor;
261 _AdoptInterfaceToCurrentDecor();
264 void
265 LookAndFeelSettingsView::_AdoptInterfaceToCurrentDecor()
267 BMenuItem* item = fDecorMenu->FindItem(fCurrentDecor);
268 if (item != NULL)
269 item->SetMarked(true);
273 bool
274 LookAndFeelSettingsView::_DoubleScrollBarArrows()
276 scroll_bar_info info;
277 get_scroll_bar_info(&info);
279 return info.double_arrows;
283 void
284 LookAndFeelSettingsView::_SetDoubleScrollBarArrows(bool doubleArrows)
286 scroll_bar_info info;
287 get_scroll_bar_info(&info);
289 info.double_arrows = doubleArrows;
290 set_scroll_bar_info(&info);
292 if (doubleArrows)
293 fArrowStyleDouble->SetValue(B_CONTROL_ON);
294 else
295 fArrowStyleSingle->SetValue(B_CONTROL_ON);
297 Window()->PostMessage(kMsgUpdate);
301 bool
302 LookAndFeelSettingsView::IsDefaultable()
304 return fCurrentDecor != fDecorUtility.DefaultDecorator()->Name()
305 || _DoubleScrollBarArrows() != false;
309 void
310 LookAndFeelSettingsView::SetDefaults()
312 _SetDecor(fDecorUtility.DefaultDecorator());
313 _SetDoubleScrollBarArrows(false);
317 bool
318 LookAndFeelSettingsView::IsRevertable()
320 return fCurrentDecor != fSavedDecor
321 || _DoubleScrollBarArrows() != fSavedDoubleArrowsValue;
325 void
326 LookAndFeelSettingsView::Revert()
328 if (IsRevertable()) {
329 _SetDecor(fSavedDecor);
330 _SetDoubleScrollBarArrows(fSavedDoubleArrowsValue);