xref: /haiku/src/apps/webpositive/SettingsWindow.cpp (revision f15270537aa959953203f8aef41bacea47f30f2e)
1 /*
2  * Copyright (C) 2010 Stephan Aßmus <superstippi@gmx.de>
3  *
4  * All rights reserved. Distributed under the terms of the MIT License.
5  */
6 #include "SettingsWindow.h"
7 
8 #include <Button.h>
9 #include <CheckBox.h>
10 #include <ControlLook.h>
11 #include <GridLayoutBuilder.h>
12 #include <GroupLayout.h>
13 #include <GroupLayoutBuilder.h>
14 #include <LayoutBuilder.h>
15 #include <Locale.h>
16 #include <MenuItem.h>
17 #include <MenuField.h>
18 #include <Message.h>
19 #include <PopUpMenu.h>
20 #include <ScrollView.h>
21 #include <SeparatorView.h>
22 #include <SpaceLayoutItem.h>
23 #include <Spinner.h>
24 #include <TabView.h>
25 #include <TextControl.h>
26 #include <debugger.h>
27 
28 #include <stdio.h>
29 #include <stdlib.h>
30 
31 #include "BrowserApp.h"
32 #include "BrowsingHistory.h"
33 #include "BrowserWindow.h"
34 #include "FontSelectionView.h"
35 #include "SettingsKeys.h"
36 #include "SettingsMessage.h"
37 #include "WebSettings.h"
38 
39 
40 #undef B_TRANSLATION_CONTEXT
41 #define B_TRANSLATION_CONTEXT "Settings Window"
42 
43 enum {
44 	MSG_APPLY									= 'aply',
45 	MSG_CANCEL									= 'cncl',
46 	MSG_REVERT									= 'rvrt',
47 
48 	MSG_START_PAGE_CHANGED						= 'hpch',
49 	MSG_SEARCH_PAGE_CHANGED						= 'spch',
50 	MSG_DOWNLOAD_FOLDER_CHANGED					= 'dnfc',
51 	MSG_NEW_WINDOWS_BEHAVIOR_CHANGED			= 'nwbc',
52 	MSG_NEW_TABS_BEHAVIOR_CHANGED				= 'ntbc',
53 	MSG_HISTORY_MENU_DAYS_CHANGED				= 'digm',
54 	MSG_TAB_DISPLAY_BEHAVIOR_CHANGED			= 'tdbc',
55 	MSG_AUTO_HIDE_INTERFACE_BEHAVIOR_CHANGED	= 'ahic',
56 	MSG_AUTO_HIDE_POINTER_BEHAVIOR_CHANGED		= 'ahpc',
57 	MSG_SHOW_HOME_BUTTON_CHANGED				= 'shbc',
58 
59 	MSG_STANDARD_FONT_CHANGED					= 'stfc',
60 	MSG_SERIF_FONT_CHANGED						= 'sefc',
61 	MSG_SANS_SERIF_FONT_CHANGED					= 'ssfc',
62 	MSG_FIXED_FONT_CHANGED						= 'ffch',
63 
64 	MSG_STANDARD_FONT_SIZE_SELECTED				= 'sfss',
65 	MSG_FIXED_FONT_SIZE_SELECTED				= 'ffss',
66 
67 	MSG_USE_PROXY_CHANGED						= 'upsc',
68 	MSG_PROXY_ADDRESS_CHANGED					= 'psac',
69 	MSG_PROXY_PORT_CHANGED						= 'pspc',
70 	MSG_USE_PROXY_AUTH_CHANGED					= 'upsa',
71 	MSG_PROXY_USERNAME_CHANGED					= 'psuc',
72 	MSG_PROXY_PASSWORD_CHANGED					= 'pswc',
73 };
74 
75 static const int32 kDefaultFontSize = 14;
76 
77 
78 SettingsWindow::SettingsWindow(BRect frame, SettingsMessage* settings)
79 	:
80 	BWindow(frame, B_TRANSLATE("Settings"), B_TITLED_WINDOW_LOOK,
81 		B_NORMAL_WINDOW_FEEL, B_AUTO_UPDATE_SIZE_LIMITS
82 			| B_ASYNCHRONOUS_CONTROLS | B_NOT_ZOOMABLE),
83 	fSettings(settings)
84 {
85 	fApplyButton = new BButton(B_TRANSLATE("Apply"), new BMessage(MSG_APPLY));
86 	fCancelButton = new BButton(B_TRANSLATE("Cancel"),
87 		new BMessage(MSG_CANCEL));
88 	fRevertButton = new BButton(B_TRANSLATE("Revert"),
89 		new BMessage(MSG_REVERT));
90 
91 	float spacing = be_control_look->DefaultItemSpacing();
92 
93 	BTabView* tabView = new BTabView("settings pages", B_WIDTH_FROM_LABEL);
94 	tabView->SetBorder(B_NO_BORDER);
95 
96 	BLayoutBuilder::Group<>(this, B_VERTICAL, 0)
97 		.SetInsets(0, B_USE_DEFAULT_SPACING, 0, B_USE_WINDOW_SPACING)
98 		.Add(tabView)
99 		.Add(new BSeparatorView(B_HORIZONTAL))
100 		.AddGroup(B_HORIZONTAL)
101 			.SetInsets(B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING,
102 				B_USE_WINDOW_SPACING, 0)
103 			.Add(fRevertButton)
104 			.AddGlue()
105 			.Add(fCancelButton)
106 			.Add(fApplyButton);
107 
108 	tabView->AddTab(_CreateGeneralPage(spacing));
109 	tabView->AddTab(_CreateFontsPage(spacing));
110 	tabView->AddTab(_CreateProxyPage(spacing));
111 
112 	_SetupFontSelectionView(fStandardFontView,
113 		new BMessage(MSG_STANDARD_FONT_CHANGED));
114 	_SetupFontSelectionView(fSerifFontView,
115 		new BMessage(MSG_SERIF_FONT_CHANGED));
116 	_SetupFontSelectionView(fSansSerifFontView,
117 		new BMessage(MSG_SANS_SERIF_FONT_CHANGED));
118 	_SetupFontSelectionView(fFixedFontView,
119 		new BMessage(MSG_FIXED_FONT_CHANGED));
120 
121 	fApplyButton->MakeDefault(true);
122 
123 	if (!frame.IsValid())
124 		CenterOnScreen();
125 
126 	// load settings from disk
127 	_RevertSettings();
128 	// apply to WebKit
129 	_ApplySettings();
130 
131 	// Start hidden
132 	Hide();
133 	Show();
134 }
135 
136 
137 SettingsWindow::~SettingsWindow()
138 {
139 	RemoveHandler(fStandardFontView);
140 	delete fStandardFontView;
141 	RemoveHandler(fSerifFontView);
142 	delete fSerifFontView;
143 	RemoveHandler(fSansSerifFontView);
144 	delete fSansSerifFontView;
145 	RemoveHandler(fFixedFontView);
146 	delete fFixedFontView;
147 }
148 
149 
150 void
151 SettingsWindow::MessageReceived(BMessage* message)
152 {
153 	switch (message->what) {
154 		case MSG_APPLY:
155 			_ApplySettings();
156 			break;
157 		case MSG_CANCEL:
158 			_RevertSettings();
159 			PostMessage(B_QUIT_REQUESTED);
160 			break;
161 		case MSG_REVERT:
162 			_RevertSettings();
163 			break;
164 
165 		case MSG_STANDARD_FONT_SIZE_SELECTED:
166 		{
167 			int32 size = _SizesMenuValue(fStandardSizesMenu->Menu());
168 			fStandardFontView->SetSize(size);
169 			fSerifFontView->SetSize(size);
170 			fSansSerifFontView->SetSize(size);
171 			_ValidateControlsEnabledStatus();
172 			break;
173 		}
174 		case MSG_FIXED_FONT_SIZE_SELECTED:
175 		{
176 			int32 size = _SizesMenuValue(fFixedSizesMenu->Menu());
177 			fFixedFontView->SetSize(size);
178 			_ValidateControlsEnabledStatus();
179 			break;
180 		}
181 
182 		case MSG_START_PAGE_CHANGED:
183 		case MSG_SEARCH_PAGE_CHANGED:
184 		case MSG_DOWNLOAD_FOLDER_CHANGED:
185 		case MSG_NEW_WINDOWS_BEHAVIOR_CHANGED:
186 		case MSG_NEW_TABS_BEHAVIOR_CHANGED:
187 		case MSG_HISTORY_MENU_DAYS_CHANGED:
188 		case MSG_TAB_DISPLAY_BEHAVIOR_CHANGED:
189 		case MSG_AUTO_HIDE_INTERFACE_BEHAVIOR_CHANGED:
190 		case MSG_AUTO_HIDE_POINTER_BEHAVIOR_CHANGED:
191 		case MSG_SHOW_HOME_BUTTON_CHANGED:
192 		case MSG_STANDARD_FONT_CHANGED:
193 		case MSG_SERIF_FONT_CHANGED:
194 		case MSG_SANS_SERIF_FONT_CHANGED:
195 		case MSG_FIXED_FONT_CHANGED:
196 		case MSG_USE_PROXY_CHANGED:
197 		case MSG_PROXY_ADDRESS_CHANGED:
198 		case MSG_PROXY_PORT_CHANGED:
199 		case MSG_USE_PROXY_AUTH_CHANGED:
200 		case MSG_PROXY_USERNAME_CHANGED:
201 		case MSG_PROXY_PASSWORD_CHANGED:
202 			// TODO: Some settings could change live, some others not?
203 			_ValidateControlsEnabledStatus();
204 			break;
205 
206 		default:
207 			BWindow::MessageReceived(message);
208 			break;
209 	}
210 }
211 
212 
213 bool
214 SettingsWindow::QuitRequested()
215 {
216 	if (!IsHidden())
217 		Hide();
218 	return false;
219 }
220 
221 
222 void
223 SettingsWindow::Show()
224 {
225 	// When showing the window, the this is always the
226 	// point to which we can revert the settings.
227 	_RevertSettings();
228 	BWindow::Show();
229 }
230 
231 
232 // #pragma mark - private
233 
234 
235 BView*
236 SettingsWindow::_CreateGeneralPage(float spacing)
237 {
238 	fStartPageControl = new BTextControl("start page",
239 		B_TRANSLATE("Start page:"), "", new BMessage(MSG_START_PAGE_CHANGED));
240 	fStartPageControl->SetModificationMessage(
241 		new BMessage(MSG_START_PAGE_CHANGED));
242 	fStartPageControl->SetText(
243 		fSettings->GetValue(kSettingsKeyStartPageURL, kDefaultStartPageURL));
244 
245 	fSearchPageControl = new BTextControl("search page",
246 		B_TRANSLATE("Search page:"), "",
247 		new BMessage(MSG_SEARCH_PAGE_CHANGED));
248 	fSearchPageControl->SetModificationMessage(
249 		new BMessage(MSG_SEARCH_PAGE_CHANGED));
250 	BString searchURL = fSettings->GetValue(kSettingsKeySearchPageURL,
251 		kDefaultSearchPageURL);
252 	if (searchURL == "http://www.google.com") {
253 		// Migrate old settings files.
254 		searchURL = kDefaultSearchPageURL;
255 		fSettings->SetValue(kSettingsKeySearchPageURL, kDefaultSearchPageURL);
256 	}
257 	fSearchPageControl->SetText(searchURL);
258 
259 	fDownloadFolderControl = new BTextControl("download folder",
260 		B_TRANSLATE("Download folder:"), "",
261 		new BMessage(MSG_DOWNLOAD_FOLDER_CHANGED));
262 	fDownloadFolderControl->SetModificationMessage(
263 		new BMessage(MSG_DOWNLOAD_FOLDER_CHANGED));
264 	fDownloadFolderControl->SetText(
265 		fSettings->GetValue(kSettingsKeyDownloadPath, kDefaultDownloadPath));
266 
267 	fNewWindowBehaviorOpenHomeItem = new BMenuItem(
268 		B_TRANSLATE("Open start page"),
269 		new BMessage(MSG_NEW_WINDOWS_BEHAVIOR_CHANGED));
270 	fNewWindowBehaviorOpenSearchItem = new BMenuItem(
271 		B_TRANSLATE("Open search page"),
272 		new BMessage(MSG_NEW_WINDOWS_BEHAVIOR_CHANGED));
273 	fNewWindowBehaviorOpenBlankItem = new BMenuItem(
274 		B_TRANSLATE("Open blank page"),
275 		new BMessage(MSG_NEW_WINDOWS_BEHAVIOR_CHANGED));
276 
277 	fNewTabBehaviorCloneCurrentItem = new BMenuItem(
278 		B_TRANSLATE("Clone current page"),
279 		new BMessage(MSG_NEW_TABS_BEHAVIOR_CHANGED));
280 	fNewTabBehaviorOpenHomeItem = new BMenuItem(
281 		B_TRANSLATE("Open start page"),
282 		new BMessage(MSG_NEW_TABS_BEHAVIOR_CHANGED));
283 	fNewTabBehaviorOpenSearchItem = new BMenuItem(
284 		B_TRANSLATE("Open search page"),
285 		new BMessage(MSG_NEW_TABS_BEHAVIOR_CHANGED));
286 	fNewTabBehaviorOpenBlankItem = new BMenuItem(
287 		B_TRANSLATE("Open blank page"),
288 		new BMessage(MSG_NEW_TABS_BEHAVIOR_CHANGED));
289 
290 	fNewWindowBehaviorOpenHomeItem->SetMarked(true);
291 	fNewTabBehaviorOpenBlankItem->SetMarked(true);
292 
293 	BPopUpMenu* newWindowBehaviorMenu = new BPopUpMenu("New windows");
294 	newWindowBehaviorMenu->AddItem(fNewWindowBehaviorOpenHomeItem);
295 	newWindowBehaviorMenu->AddItem(fNewWindowBehaviorOpenSearchItem);
296 	newWindowBehaviorMenu->AddItem(fNewWindowBehaviorOpenBlankItem);
297 	fNewWindowBehaviorMenu = new BMenuField("new window behavior",
298 		B_TRANSLATE("New windows:"), newWindowBehaviorMenu);
299 
300 	BPopUpMenu* newTabBehaviorMenu = new BPopUpMenu("New tabs");
301 	newTabBehaviorMenu->AddItem(fNewTabBehaviorOpenBlankItem);
302 	newTabBehaviorMenu->AddItem(fNewTabBehaviorOpenHomeItem);
303 	newTabBehaviorMenu->AddItem(fNewTabBehaviorOpenSearchItem);
304 	newTabBehaviorMenu->AddItem(fNewTabBehaviorCloneCurrentItem);
305 	fNewTabBehaviorMenu = new BMenuField("new tab behavior",
306 		B_TRANSLATE("New tabs:"), newTabBehaviorMenu);
307 
308 	fDaysInHistory = new BSpinner("days in history",
309 		B_TRANSLATE("Number of days to keep links in History menu:"),
310 		new BMessage(MSG_HISTORY_MENU_DAYS_CHANGED));
311 	fDaysInHistory->SetRange(1, 35);
312 	fDaysInHistory->SetValue(
313 		BrowsingHistory::DefaultInstance()->MaxHistoryItemAge());
314 
315 	fShowTabsIfOnlyOnePage = new BCheckBox("show tabs if only one page",
316 		B_TRANSLATE("Show tabs if only one page is open"),
317 		new BMessage(MSG_TAB_DISPLAY_BEHAVIOR_CHANGED));
318 	fShowTabsIfOnlyOnePage->SetValue(B_CONTROL_ON);
319 
320 	fAutoHideInterfaceInFullscreenMode = new BCheckBox("auto-hide interface",
321 		B_TRANSLATE("Auto-hide interface in full screen mode"),
322 		new BMessage(MSG_AUTO_HIDE_INTERFACE_BEHAVIOR_CHANGED));
323 	fAutoHideInterfaceInFullscreenMode->SetValue(B_CONTROL_OFF);
324 
325 	fAutoHidePointer = new BCheckBox("auto-hide pointer",
326 		B_TRANSLATE("Auto-hide mouse pointer"),
327 		new BMessage(MSG_AUTO_HIDE_POINTER_BEHAVIOR_CHANGED));
328 	fAutoHidePointer->SetValue(B_CONTROL_OFF);
329 
330 	fShowHomeButton = new BCheckBox("show home button",
331 		B_TRANSLATE("Show home button"),
332 		new BMessage(MSG_SHOW_HOME_BUTTON_CHANGED));
333 	fShowHomeButton->SetValue(B_CONTROL_ON);
334 
335 	BView* view = BGroupLayoutBuilder(B_VERTICAL, 0)
336 		.Add(BGridLayoutBuilder(spacing / 2, spacing / 2)
337 			.Add(fStartPageControl->CreateLabelLayoutItem(), 0, 0)
338 			.Add(fStartPageControl->CreateTextViewLayoutItem(), 1, 0)
339 
340 			.Add(fSearchPageControl->CreateLabelLayoutItem(), 0, 1)
341 			.Add(fSearchPageControl->CreateTextViewLayoutItem(), 1, 1)
342 
343 			.Add(fDownloadFolderControl->CreateLabelLayoutItem(), 0, 2)
344 			.Add(fDownloadFolderControl->CreateTextViewLayoutItem(), 1, 2)
345 
346 			.Add(fNewWindowBehaviorMenu->CreateLabelLayoutItem(), 0, 3)
347 			.Add(fNewWindowBehaviorMenu->CreateMenuBarLayoutItem(), 1, 3)
348 
349 			.Add(fNewTabBehaviorMenu->CreateLabelLayoutItem(), 0, 4)
350 			.Add(fNewTabBehaviorMenu->CreateMenuBarLayoutItem(), 1, 4)
351 		)
352 		.Add(BSpaceLayoutItem::CreateVerticalStrut(spacing))
353 		.Add(new BSeparatorView(B_HORIZONTAL, B_PLAIN_BORDER))
354 		.Add(BSpaceLayoutItem::CreateVerticalStrut(spacing))
355 		.Add(fShowTabsIfOnlyOnePage)
356 		.Add(fAutoHideInterfaceInFullscreenMode)
357 		.Add(fAutoHidePointer)
358 		.Add(fShowHomeButton)
359 		.Add(BSpaceLayoutItem::CreateVerticalStrut(spacing))
360 
361 		.Add(fDaysInHistory)
362 		.AddGlue()
363 		.SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING,
364 			B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING)
365 		.TopView()
366 	;
367 	view->SetName(B_TRANSLATE("General"));
368 	return view;
369 }
370 
371 
372 BView*
373 SettingsWindow::_CreateFontsPage(float spacing)
374 {
375 	fStandardFontView = new FontSelectionView("standard",
376 		B_TRANSLATE("Standard font:"), true, be_plain_font);
377 	BFont defaultSerifFont = _FindDefaultSerifFont();
378 	fSerifFontView = new FontSelectionView("serif",
379 		B_TRANSLATE("Serif font:"), true, &defaultSerifFont);
380 	fSansSerifFontView = new FontSelectionView("sans serif",
381 		B_TRANSLATE("Sans serif font:"), true, be_plain_font);
382 	fFixedFontView = new FontSelectionView("fixed",
383 		B_TRANSLATE("Fixed font:"), true, be_fixed_font);
384 
385 	fStandardSizesMenu =  new BMenuField("standard font size",
386 		B_TRANSLATE("Default standard font size:"), new BPopUpMenu("sizes"),
387 		B_WILL_DRAW);
388 	fStandardSizesMenu->SetAlignment(B_ALIGN_RIGHT);
389 
390 	_BuildSizesMenu(fStandardSizesMenu->Menu(),
391 		MSG_STANDARD_FONT_SIZE_SELECTED);
392 
393 	fFixedSizesMenu =  new BMenuField("fixed font size",
394 		B_TRANSLATE("Default fixed font size:"), new BPopUpMenu("sizes"),
395 		B_WILL_DRAW);
396 	fFixedSizesMenu->SetAlignment(B_ALIGN_RIGHT);
397 
398 	_BuildSizesMenu(fFixedSizesMenu->Menu(), MSG_FIXED_FONT_SIZE_SELECTED);
399 
400 	BView* view = BGridLayoutBuilder(spacing / 2, spacing / 2)
401 		.Add(fStandardFontView->CreateFontsLabelLayoutItem(), 0, 0)
402 		.Add(fStandardFontView->CreateFontsMenuBarLayoutItem(), 1, 0)
403 		.Add(fStandardSizesMenu->CreateLabelLayoutItem(), 2, 0)
404 		.Add(fStandardSizesMenu->CreateMenuBarLayoutItem(), 3, 0)
405 		.Add(fStandardFontView->PreviewBox(), 1, 1, 3)
406 		.Add(fSerifFontView->CreateFontsLabelLayoutItem(), 0, 2)
407 		.Add(fSerifFontView->CreateFontsMenuBarLayoutItem(), 1, 2)
408 		.Add(fSerifFontView->PreviewBox(), 1, 3, 3)
409 		.Add(fSansSerifFontView->CreateFontsLabelLayoutItem(), 0, 4)
410 		.Add(fSansSerifFontView->CreateFontsMenuBarLayoutItem(), 1, 4)
411 		.Add(fSansSerifFontView->PreviewBox(), 1, 5, 3)
412 		.Add(BSpaceLayoutItem::CreateVerticalStrut(spacing / 2), 0, 6, 2)
413 		.Add(fFixedFontView->CreateFontsLabelLayoutItem(), 0, 7)
414 		.Add(fFixedFontView->CreateFontsMenuBarLayoutItem(), 1, 7)
415 		.Add(fFixedSizesMenu->CreateLabelLayoutItem(), 2, 7)
416 		.Add(fFixedSizesMenu->CreateMenuBarLayoutItem(), 3, 7)
417 		.Add(fFixedFontView->PreviewBox(), 1, 8, 3)
418 		.SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING,
419 			B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING)
420 		.View();
421 
422 	view->SetName(B_TRANSLATE("Fonts"));
423 	return view;
424 }
425 
426 
427 BView*
428 SettingsWindow::_CreateProxyPage(float spacing)
429 {
430 	fUseProxyCheckBox = new BCheckBox("use proxy",
431 		B_TRANSLATE("Use proxy server to connect to the internet"),
432 		new BMessage(MSG_USE_PROXY_CHANGED));
433 	fUseProxyCheckBox->SetValue(B_CONTROL_ON);
434 
435 	fProxyAddressControl = new BTextControl("proxy address",
436 		B_TRANSLATE("Proxy server address:"), "",
437 		new BMessage(MSG_PROXY_ADDRESS_CHANGED));
438 	fProxyAddressControl->SetModificationMessage(
439 		new BMessage(MSG_PROXY_ADDRESS_CHANGED));
440 	fProxyAddressControl->SetText(
441 		fSettings->GetValue(kSettingsKeyProxyAddress, ""));
442 
443 	fProxyPortControl = new BTextControl("proxy port",
444 		B_TRANSLATE("Proxy server port:"), "",
445 		new BMessage(MSG_PROXY_PORT_CHANGED));
446 	fProxyPortControl->SetModificationMessage(
447 		new BMessage(MSG_PROXY_PORT_CHANGED));
448 	fProxyPortControl->SetText(
449 		fSettings->GetValue(kSettingsKeyProxyPort, ""));
450 
451 	fUseProxyAuthCheckBox = new BCheckBox("use authentication",
452 		B_TRANSLATE("Proxy server requires authentication"),
453 		new BMessage(MSG_USE_PROXY_AUTH_CHANGED));
454 	fUseProxyAuthCheckBox->SetValue(B_CONTROL_ON);
455 
456 	fProxyUsernameControl = new BTextControl("proxy username",
457 		B_TRANSLATE("Proxy username:"), "",
458 		new BMessage(MSG_PROXY_USERNAME_CHANGED));
459 	fProxyUsernameControl->SetModificationMessage(
460 		new BMessage(MSG_PROXY_USERNAME_CHANGED));
461 	fProxyUsernameControl->SetText(
462 		fSettings->GetValue(kSettingsKeyProxyUsername, ""));
463 
464 	fProxyPasswordControl = new BTextControl("proxy password",
465 		B_TRANSLATE("Proxy password:"), "",
466 		new BMessage(MSG_PROXY_PASSWORD_CHANGED));
467 	fProxyPasswordControl->SetModificationMessage(
468 		new BMessage(MSG_PROXY_PASSWORD_CHANGED));
469 	fProxyPasswordControl->TextView()->HideTyping(true);
470 	fProxyPasswordControl->SetText(
471 		fSettings->GetValue(kSettingsKeyProxyPassword, ""));
472 
473 	BView* view = BGroupLayoutBuilder(B_VERTICAL, 0)
474 		.Add(fUseProxyCheckBox)
475 		.Add(BGridLayoutBuilder(spacing / 2, spacing / 2)
476 			.Add(fProxyAddressControl->CreateLabelLayoutItem(), 0, 0)
477 			.Add(fProxyAddressControl->CreateTextViewLayoutItem(), 1, 0)
478 
479 			.Add(fProxyPortControl->CreateLabelLayoutItem(), 0, 1)
480 			.Add(fProxyPortControl->CreateTextViewLayoutItem(), 1, 1)
481 		)
482 		.Add(BSpaceLayoutItem::CreateVerticalStrut(spacing))
483 		.Add(fUseProxyAuthCheckBox)
484 		.Add(BGridLayoutBuilder(spacing / 2, spacing / 2)
485 			.Add(fProxyUsernameControl->CreateLabelLayoutItem(), 0, 0)
486 			.Add(fProxyUsernameControl->CreateTextViewLayoutItem(), 1, 0)
487 
488 			.Add(fProxyPasswordControl->CreateLabelLayoutItem(), 0, 1)
489 			.Add(fProxyPasswordControl->CreateTextViewLayoutItem(), 1, 1)
490 		)
491 		.Add(BSpaceLayoutItem::CreateGlue())
492 
493 		.SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING,
494 			B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING)
495 
496 		.TopView()
497 	;
498 	view->SetName(B_TRANSLATE("Proxy server"));
499 	return view;
500 }
501 
502 
503 void
504 SettingsWindow::_BuildSizesMenu(BMenu* menu, uint32 messageWhat)
505 {
506 	const float kMinSize = 8.0;
507 	const float kMaxSize = 18.0;
508 
509 	const int32 kSizes[] = {7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 21, 24, 0};
510 
511 	for (int32 i = 0; kSizes[i]; i++) {
512 		int32 size = kSizes[i];
513 		if (size < kMinSize || size > kMaxSize)
514 			continue;
515 
516 		char label[32];
517 		snprintf(label, sizeof(label), "%" B_PRId32, size);
518 
519 		BMessage* message = new BMessage(messageWhat);
520 		message->AddInt32("size", size);
521 
522 		BMenuItem* item = new BMenuItem(label, message);
523 
524 		menu->AddItem(item);
525 		item->SetTarget(this);
526 	}
527 }
528 
529 
530 void
531 SettingsWindow::_SetupFontSelectionView(FontSelectionView* view,
532 	BMessage* message)
533 {
534 	AddHandler(view);
535 	view->AttachedToLooper();
536 	view->SetMessage(message);
537 	view->SetTarget(this);
538 }
539 
540 
541 // #pragma mark -
542 
543 
544 bool
545 SettingsWindow::_CanApplySettings() const
546 {
547 	bool canApply = false;
548 
549 	// General settings
550 	canApply = canApply || (strcmp(fStartPageControl->Text(),
551 		fSettings->GetValue(kSettingsKeyStartPageURL,
552 			kDefaultStartPageURL)) != 0);
553 
554 	canApply = canApply || (strcmp(fSearchPageControl->Text(),
555 		fSettings->GetValue(kSettingsKeySearchPageURL,
556 			kDefaultSearchPageURL)) != 0);
557 
558 	canApply = canApply || (strcmp(fDownloadFolderControl->Text(),
559 		fSettings->GetValue(kSettingsKeyDownloadPath,
560 			kDefaultDownloadPath)) != 0);
561 
562 	canApply = canApply || ((fShowTabsIfOnlyOnePage->Value() == B_CONTROL_ON)
563 		!= fSettings->GetValue(kSettingsKeyShowTabsIfSinglePageOpen, true));
564 
565 	canApply = canApply || (
566 		(fAutoHideInterfaceInFullscreenMode->Value() == B_CONTROL_ON)
567 		!= fSettings->GetValue(kSettingsKeyAutoHideInterfaceInFullscreenMode,
568 			false));
569 
570 	canApply = canApply || (
571 		(fAutoHidePointer->Value() == B_CONTROL_ON)
572 		!= fSettings->GetValue(kSettingsKeyAutoHidePointer, false));
573 
574 	canApply = canApply || ((fShowHomeButton->Value() == B_CONTROL_ON)
575 		!= fSettings->GetValue(kSettingsKeyShowHomeButton, true));
576 
577 	canApply = canApply || (fDaysInHistory->Value()
578 		!= BrowsingHistory::DefaultInstance()->MaxHistoryItemAge());
579 
580 	// New window policy
581 	canApply = canApply || (_NewWindowPolicy()
582 		!= fSettings->GetValue(kSettingsKeyNewWindowPolicy,
583 			(uint32)OpenStartPage));
584 
585 	// New tab policy
586 	canApply = canApply || (_NewTabPolicy()
587 		!= fSettings->GetValue(kSettingsKeyNewTabPolicy,
588 			(uint32)OpenBlankPage));
589 
590 	// Font settings
591 	canApply = canApply || (fStandardFontView->Font()
592 		!= fSettings->GetValue("standard font", *be_plain_font));
593 
594 	canApply = canApply || (fSerifFontView->Font()
595 		!= fSettings->GetValue("serif font", _FindDefaultSerifFont()));
596 
597 	canApply = canApply || (fSansSerifFontView->Font()
598 		!= fSettings->GetValue("sans serif font", *be_plain_font));
599 
600 	canApply = canApply || (fFixedFontView->Font()
601 		!= fSettings->GetValue("fixed font", *be_fixed_font));
602 
603 	canApply = canApply || (_SizesMenuValue(fStandardSizesMenu->Menu())
604 		!= fSettings->GetValue("standard font size", kDefaultFontSize));
605 
606 	canApply = canApply || (_SizesMenuValue(fFixedSizesMenu->Menu())
607 		!= fSettings->GetValue("fixed font size", kDefaultFontSize));
608 
609 	// Proxy settings
610 	canApply = canApply || ((fUseProxyCheckBox->Value() == B_CONTROL_ON)
611 		!= fSettings->GetValue(kSettingsKeyUseProxy, false));
612 
613 	canApply = canApply || (strcmp(fProxyAddressControl->Text(),
614 		fSettings->GetValue(kSettingsKeyProxyAddress, "")) != 0);
615 
616 	canApply = canApply || (_ProxyPort()
617 		!= fSettings->GetValue(kSettingsKeyProxyPort, (uint32)0));
618 
619 	canApply = canApply || ((fUseProxyAuthCheckBox->Value() == B_CONTROL_ON)
620 		!= fSettings->GetValue(kSettingsKeyUseProxyAuth, false));
621 
622 	canApply = canApply || (strcmp(fProxyUsernameControl->Text(),
623 		fSettings->GetValue(kSettingsKeyProxyUsername, "")) != 0);
624 
625 	canApply = canApply || (strcmp(fProxyPasswordControl->Text(),
626 		fSettings->GetValue(kSettingsKeyProxyPassword, "")) != 0);
627 
628 	return canApply;
629 }
630 
631 
632 void
633 SettingsWindow::_ApplySettings()
634 {
635 	// Store general settings
636 	BrowsingHistory::DefaultInstance()->SetMaxHistoryItemAge(
637 		(uint32)fDaysInHistory->Value());
638 	fSettings->SetValue(kSettingsKeyStartPageURL, fStartPageControl->Text());
639 	fSettings->SetValue(kSettingsKeySearchPageURL, fSearchPageControl->Text());
640 	fSettings->SetValue(kSettingsKeyDownloadPath, fDownloadFolderControl->Text());
641 	fSettings->SetValue(kSettingsKeyShowTabsIfSinglePageOpen,
642 		fShowTabsIfOnlyOnePage->Value() == B_CONTROL_ON);
643 	fSettings->SetValue(kSettingsKeyAutoHideInterfaceInFullscreenMode,
644 		fAutoHideInterfaceInFullscreenMode->Value() == B_CONTROL_ON);
645 	fSettings->SetValue(kSettingsKeyAutoHidePointer,
646 		fAutoHidePointer->Value() == B_CONTROL_ON);
647 	fSettings->SetValue(kSettingsKeyShowHomeButton,
648 		fShowHomeButton->Value() == B_CONTROL_ON);
649 
650 	// New page policies
651 	fSettings->SetValue(kSettingsKeyNewWindowPolicy, _NewWindowPolicy());
652 	fSettings->SetValue(kSettingsKeyNewTabPolicy, _NewTabPolicy());
653 
654 	// Store fond settings
655 	fSettings->SetValue("standard font", fStandardFontView->Font());
656 	fSettings->SetValue("serif font", fSerifFontView->Font());
657 	fSettings->SetValue("sans serif font", fSansSerifFontView->Font());
658 	fSettings->SetValue("fixed font", fFixedFontView->Font());
659 	int32 standardFontSize = _SizesMenuValue(fStandardSizesMenu->Menu());
660 	int32 fixedFontSize = _SizesMenuValue(fFixedSizesMenu->Menu());
661 	fSettings->SetValue("standard font size", standardFontSize);
662 	fSettings->SetValue("fixed font size", fixedFontSize);
663 
664 	// Store proxy settings
665 
666 	fSettings->SetValue(kSettingsKeyUseProxy,
667 		fUseProxyCheckBox->Value() == B_CONTROL_ON);
668 	fSettings->SetValue(kSettingsKeyProxyAddress,
669 		fProxyAddressControl->Text());
670 	uint32 proxyPort = _ProxyPort();
671 	fSettings->SetValue(kSettingsKeyProxyPort, proxyPort);
672 	fSettings->SetValue(kSettingsKeyUseProxyAuth,
673 		fUseProxyAuthCheckBox->Value() == B_CONTROL_ON);
674 	fSettings->SetValue(kSettingsKeyProxyUsername,
675 		fProxyUsernameControl->Text());
676 	fSettings->SetValue(kSettingsKeyProxyPassword,
677 		fProxyPasswordControl->Text());
678 
679 	fSettings->Save();
680 
681 	// Apply settings to default web page settings.
682 	BWebSettings::Default()->SetStandardFont(fStandardFontView->Font());
683 	BWebSettings::Default()->SetSerifFont(fSerifFontView->Font());
684 	BWebSettings::Default()->SetSansSerifFont(fSansSerifFontView->Font());
685 	BWebSettings::Default()->SetFixedFont(fFixedFontView->Font());
686 	BWebSettings::Default()->SetDefaultStandardFontSize(standardFontSize);
687 	BWebSettings::Default()->SetDefaultFixedFontSize(fixedFontSize);
688 
689 	if (fUseProxyCheckBox->Value() == B_CONTROL_ON) {
690 		if (fUseProxyAuthCheckBox->Value() == B_CONTROL_ON) {
691 			BWebSettings::Default()->SetProxyInfo(fProxyAddressControl->Text(),
692 				proxyPort, B_PROXY_TYPE_HTTP, fProxyUsernameControl->Text(),
693 				fProxyPasswordControl->Text());
694 		} else {
695 			BWebSettings::Default()->SetProxyInfo(fProxyAddressControl->Text(),
696 				proxyPort, B_PROXY_TYPE_HTTP, "", "");
697 		}
698 	} else
699 		BWebSettings::Default()->SetProxyInfo();
700 
701 	// This will find all currently instantiated page settings and apply
702 	// the default values, unless the page settings have local overrides.
703 	BWebSettings::Default()->Apply();
704 
705 	_ValidateControlsEnabledStatus();
706 }
707 
708 
709 void
710 SettingsWindow::_RevertSettings()
711 {
712 	fStartPageControl->SetText(
713 		fSettings->GetValue(kSettingsKeyStartPageURL, kDefaultStartPageURL));
714 
715 	fSearchPageControl->SetText(
716 		fSettings->GetValue(kSettingsKeySearchPageURL, kDefaultSearchPageURL));
717 
718 	fDownloadFolderControl->SetText(
719 		fSettings->GetValue(kSettingsKeyDownloadPath, kDefaultDownloadPath));
720 	fShowTabsIfOnlyOnePage->SetValue(
721 		fSettings->GetValue(kSettingsKeyShowTabsIfSinglePageOpen, true));
722 	fAutoHideInterfaceInFullscreenMode->SetValue(
723 		fSettings->GetValue(kSettingsKeyAutoHideInterfaceInFullscreenMode,
724 			false));
725 	fAutoHidePointer->SetValue(
726 		fSettings->GetValue(kSettingsKeyAutoHidePointer, false));
727 	fShowHomeButton->SetValue(
728 		fSettings->GetValue(kSettingsKeyShowHomeButton, true));
729 
730 	fDaysInHistory->SetValue(
731 		BrowsingHistory::DefaultInstance()->MaxHistoryItemAge());
732 
733 	// New window policy
734 	uint32 newWindowPolicy = fSettings->GetValue(kSettingsKeyNewWindowPolicy,
735 		(uint32)OpenStartPage);
736 	switch (newWindowPolicy) {
737 		default:
738 		case OpenStartPage:
739 			fNewWindowBehaviorOpenHomeItem->SetMarked(true);
740 			break;
741 		case OpenSearchPage:
742 			fNewWindowBehaviorOpenSearchItem->SetMarked(true);
743 			break;
744 		case OpenBlankPage:
745 			fNewWindowBehaviorOpenBlankItem->SetMarked(true);
746 			break;
747 	}
748 
749 	// New tab policy
750 	uint32 newTabPolicy = fSettings->GetValue(kSettingsKeyNewTabPolicy,
751 		(uint32)OpenBlankPage);
752 	switch (newTabPolicy) {
753 		default:
754 		case OpenBlankPage:
755 			fNewTabBehaviorOpenBlankItem->SetMarked(true);
756 			break;
757 		case OpenStartPage:
758 			fNewTabBehaviorOpenHomeItem->SetMarked(true);
759 			break;
760 		case OpenSearchPage:
761 			fNewTabBehaviorOpenSearchItem->SetMarked(true);
762 			break;
763 		case CloneCurrentPage:
764 			fNewTabBehaviorCloneCurrentItem->SetMarked(true);
765 			break;
766 	}
767 
768 	// Font settings
769 	int32 defaultFontSize = fSettings->GetValue("standard font size",
770 		kDefaultFontSize);
771 	int32 defaultFixedFontSize = fSettings->GetValue("fixed font size",
772 		kDefaultFontSize);
773 
774 	_SetSizesMenuValue(fStandardSizesMenu->Menu(), defaultFontSize);
775 	_SetSizesMenuValue(fFixedSizesMenu->Menu(), defaultFixedFontSize);
776 
777 	fStandardFontView->SetFont(fSettings->GetValue("standard font",
778 		*be_plain_font), defaultFontSize);
779 	fSerifFontView->SetFont(fSettings->GetValue("serif font",
780 		_FindDefaultSerifFont()), defaultFontSize);
781 	fSansSerifFontView->SetFont(fSettings->GetValue("sans serif font",
782 		*be_plain_font), defaultFontSize);
783 	fFixedFontView->SetFont(fSettings->GetValue("fixed font",
784 		*be_fixed_font), defaultFixedFontSize);
785 
786 	// Proxy settings
787 	fUseProxyCheckBox->SetValue(fSettings->GetValue(kSettingsKeyUseProxy,
788 		false));
789 	fProxyAddressControl->SetText(fSettings->GetValue(kSettingsKeyProxyAddress,
790 		""));
791 	BString keyProxyPort;
792 	keyProxyPort << fSettings->GetValue(kSettingsKeyProxyPort, (uint32)0);
793 	fProxyPortControl->SetText(keyProxyPort.String());
794 	fUseProxyAuthCheckBox->SetValue(fSettings->GetValue(kSettingsKeyUseProxyAuth,
795 		false));
796 	fProxyUsernameControl->SetText(fSettings->GetValue(kSettingsKeyProxyUsername,
797 		""));
798 	fProxyPasswordControl->SetText(fSettings->GetValue(kSettingsKeyProxyPassword,
799 		""));
800 
801 	_ValidateControlsEnabledStatus();
802 }
803 
804 
805 void
806 SettingsWindow::_ValidateControlsEnabledStatus()
807 {
808 	bool canApply = _CanApplySettings();
809 	fApplyButton->SetEnabled(canApply);
810 	fRevertButton->SetEnabled(canApply);
811 	// Let the Cancel button be enabled always, as another way to close the
812 	// window...
813 	fCancelButton->SetEnabled(true);
814 
815 	bool useProxy = fUseProxyCheckBox->Value() == B_CONTROL_ON;
816 	fProxyAddressControl->SetEnabled(useProxy);
817 	fProxyPortControl->SetEnabled(useProxy);
818 	fUseProxyAuthCheckBox->SetEnabled(useProxy);
819 	bool useProxyAuth = useProxy && fUseProxyAuthCheckBox->Value() == B_CONTROL_ON;
820 	fProxyUsernameControl->SetEnabled(useProxyAuth);
821 	fProxyPasswordControl->SetEnabled(useProxyAuth);
822 }
823 
824 
825 // #pragma mark -
826 
827 
828 uint32
829 SettingsWindow::_NewWindowPolicy() const
830 {
831 	uint32 newWindowPolicy = OpenStartPage;
832 	BMenuItem* markedItem = fNewWindowBehaviorMenu->Menu()->FindMarked();
833 	if (markedItem == fNewWindowBehaviorOpenSearchItem)
834 		newWindowPolicy = OpenSearchPage;
835 	else if (markedItem == fNewWindowBehaviorOpenBlankItem)
836 		newWindowPolicy = OpenBlankPage;
837 	return newWindowPolicy;
838 }
839 
840 
841 uint32
842 SettingsWindow::_NewTabPolicy() const
843 {
844 	uint32 newTabPolicy = OpenBlankPage;
845 	BMenuItem* markedItem = fNewTabBehaviorMenu->Menu()->FindMarked();
846 	if (markedItem == fNewTabBehaviorCloneCurrentItem)
847 		newTabPolicy = CloneCurrentPage;
848 	else if (markedItem == fNewTabBehaviorOpenHomeItem)
849 		newTabPolicy = OpenStartPage;
850 	else if (markedItem == fNewTabBehaviorOpenSearchItem)
851 		newTabPolicy = OpenSearchPage;
852 	return newTabPolicy;
853 }
854 
855 
856 void
857 SettingsWindow::_SetSizesMenuValue(BMenu* menu, int32 value)
858 {
859 	for (int32 i = 0; BMenuItem* item = menu->ItemAt(i); i++) {
860 		bool marked = false;
861 		if (BMessage* message = item->Message()) {
862 			int32 size;
863 			if (message->FindInt32("size", &size) == B_OK && size == value)
864 				marked = true;
865 		}
866 		item->SetMarked(marked);
867 	}
868 }
869 
870 
871 int32
872 SettingsWindow::_SizesMenuValue(BMenu* menu) const
873 {
874 	if (BMenuItem* item = menu->FindMarked()) {
875 		if (BMessage* message = item->Message()) {
876 			int32 size;
877 			if (message->FindInt32("size", &size) == B_OK)
878 				return size;
879 		}
880 	}
881 	return kDefaultFontSize;
882 }
883 
884 
885 BFont
886 SettingsWindow::_FindDefaultSerifFont() const
887 {
888 	// Default to the first "serif" font we find.
889 	BFont serifFont(*be_plain_font);
890 	font_family family;
891 	int32 familyCount = count_font_families();
892 	for (int32 i = 0; i < familyCount; i++) {
893 		if (get_font_family(i, &family) == B_OK) {
894 			BString familyString(family);
895 			if (familyString.IFindFirst("sans") >= 0)
896 				continue;
897 			if (familyString.IFindFirst("serif") >= 0) {
898 				serifFont.SetFamilyAndFace(family, B_REGULAR_FACE);
899 				break;
900 			}
901 		}
902 	}
903 	return serifFont;
904 }
905 
906 
907 uint32
908 SettingsWindow::_ProxyPort() const
909 {
910 	return atoul(fProxyPortControl->Text());
911 }
912 
913 
914