xref: /haiku/src/apps/webpositive/SettingsWindow.cpp (revision e433b3cfc3f089f7681f6d4e81d43f950ca6a440)
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::CreateHorizontalStrut(spacing))
353 		.Add(new BSeparatorView(B_HORIZONTAL, B_PLAIN_BORDER))
354 		.Add(BSpaceLayoutItem::CreateHorizontalStrut(spacing))
355 		.Add(fShowTabsIfOnlyOnePage)
356 		.Add(fAutoHideInterfaceInFullscreenMode)
357 		.Add(fAutoHidePointer)
358 		.Add(fShowHomeButton)
359 		.Add(BSpaceLayoutItem::CreateHorizontalStrut(spacing))
360 		.Add(fDaysInHistory)
361 
362 		.SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING,
363 			B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING)
364 
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 	_BuildSizesMenu(fStandardSizesMenu->Menu(),
389 		MSG_STANDARD_FONT_SIZE_SELECTED);
390 
391 	fFixedSizesMenu =  new BMenuField("fixed font size",
392 		B_TRANSLATE("Default fixed font size:"), new BPopUpMenu("sizes"),
393 		B_WILL_DRAW);
394 	_BuildSizesMenu(fFixedSizesMenu->Menu(), MSG_FIXED_FONT_SIZE_SELECTED);
395 
396 	BView* view = BGridLayoutBuilder(spacing / 2, spacing / 2)
397 		.Add(fStandardFontView->CreateFontsLabelLayoutItem(), 0, 0)
398 		.Add(fStandardFontView->CreateFontsMenuBarLayoutItem(), 1, 0)
399 		.Add(fStandardFontView->PreviewBox(), 0, 1, 2)
400 		.Add(BSpaceLayoutItem::CreateHorizontalStrut(spacing), 0, 2, 2)
401 
402 		.Add(fSerifFontView->CreateFontsLabelLayoutItem(), 0, 3)
403 		.Add(fSerifFontView->CreateFontsMenuBarLayoutItem(), 1, 3)
404 		.Add(fSerifFontView->PreviewBox(), 0, 4, 2)
405 		.Add(BSpaceLayoutItem::CreateHorizontalStrut(spacing), 0, 5, 2)
406 
407 		.Add(fSansSerifFontView->CreateFontsLabelLayoutItem(), 0, 6)
408 		.Add(fSansSerifFontView->CreateFontsMenuBarLayoutItem(), 1, 6)
409 		.Add(fSansSerifFontView->PreviewBox(), 0, 7, 2)
410 		.Add(BSpaceLayoutItem::CreateHorizontalStrut(spacing), 0, 8, 2)
411 
412 		.Add(fFixedFontView->CreateFontsLabelLayoutItem(), 0, 9)
413 		.Add(fFixedFontView->CreateFontsMenuBarLayoutItem(), 1, 9)
414 		.Add(fFixedFontView->PreviewBox(), 0, 10, 2)
415 		.Add(BSpaceLayoutItem::CreateHorizontalStrut(spacing), 0, 11, 2)
416 
417 		.Add(fStandardSizesMenu->CreateLabelLayoutItem(), 0, 12)
418 		.Add(fStandardSizesMenu->CreateMenuBarLayoutItem(), 1, 12)
419 		.Add(fFixedSizesMenu->CreateLabelLayoutItem(), 0, 13)
420 		.Add(fFixedSizesMenu->CreateMenuBarLayoutItem(), 1, 13)
421 
422 		.SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING,
423 			B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING)
424 
425 		.View()
426 	;
427 
428 	view->SetName(B_TRANSLATE("Fonts"));
429 	return view;
430 }
431 
432 
433 BView*
434 SettingsWindow::_CreateProxyPage(float spacing)
435 {
436 	fUseProxyCheckBox = new BCheckBox("use proxy",
437 		B_TRANSLATE("Use proxy server to connect to the internet"),
438 		new BMessage(MSG_USE_PROXY_CHANGED));
439 	fUseProxyCheckBox->SetValue(B_CONTROL_ON);
440 
441 	fProxyAddressControl = new BTextControl("proxy address",
442 		B_TRANSLATE("Proxy server address:"), "",
443 		new BMessage(MSG_PROXY_ADDRESS_CHANGED));
444 	fProxyAddressControl->SetModificationMessage(
445 		new BMessage(MSG_PROXY_ADDRESS_CHANGED));
446 	fProxyAddressControl->SetText(
447 		fSettings->GetValue(kSettingsKeyProxyAddress, ""));
448 
449 	fProxyPortControl = new BTextControl("proxy port",
450 		B_TRANSLATE("Proxy server port:"), "",
451 		new BMessage(MSG_PROXY_PORT_CHANGED));
452 	fProxyPortControl->SetModificationMessage(
453 		new BMessage(MSG_PROXY_PORT_CHANGED));
454 	fProxyPortControl->SetText(
455 		fSettings->GetValue(kSettingsKeyProxyPort, ""));
456 
457 	fUseProxyAuthCheckBox = new BCheckBox("use authentication",
458 		B_TRANSLATE("Proxy server requires authentication"),
459 		new BMessage(MSG_USE_PROXY_AUTH_CHANGED));
460 	fUseProxyAuthCheckBox->SetValue(B_CONTROL_ON);
461 
462 	fProxyUsernameControl = new BTextControl("proxy username",
463 		B_TRANSLATE("Proxy username:"), "",
464 		new BMessage(MSG_PROXY_USERNAME_CHANGED));
465 	fProxyUsernameControl->SetModificationMessage(
466 		new BMessage(MSG_PROXY_USERNAME_CHANGED));
467 	fProxyUsernameControl->SetText(
468 		fSettings->GetValue(kSettingsKeyProxyUsername, ""));
469 
470 	fProxyPasswordControl = new BTextControl("proxy password",
471 		B_TRANSLATE("Proxy password:"), "",
472 		new BMessage(MSG_PROXY_PASSWORD_CHANGED));
473 	fProxyPasswordControl->SetModificationMessage(
474 		new BMessage(MSG_PROXY_PASSWORD_CHANGED));
475 	fProxyPasswordControl->TextView()->HideTyping(true);
476 	fProxyPasswordControl->SetText(
477 		fSettings->GetValue(kSettingsKeyProxyPassword, ""));
478 
479 	BView* view = BGroupLayoutBuilder(B_VERTICAL, 0)
480 		.Add(fUseProxyCheckBox)
481 		.Add(BGridLayoutBuilder(spacing / 2, spacing / 2)
482 			.Add(fProxyAddressControl->CreateLabelLayoutItem(), 0, 0)
483 			.Add(fProxyAddressControl->CreateTextViewLayoutItem(), 1, 0)
484 
485 			.Add(fProxyPortControl->CreateLabelLayoutItem(), 0, 1)
486 			.Add(fProxyPortControl->CreateTextViewLayoutItem(), 1, 1)
487 		)
488 		.Add(BSpaceLayoutItem::CreateVerticalStrut(spacing))
489 		.Add(fUseProxyAuthCheckBox)
490 		.Add(BGridLayoutBuilder(spacing / 2, spacing / 2)
491 			.Add(fProxyUsernameControl->CreateLabelLayoutItem(), 0, 0)
492 			.Add(fProxyUsernameControl->CreateTextViewLayoutItem(), 1, 0)
493 
494 			.Add(fProxyPasswordControl->CreateLabelLayoutItem(), 0, 1)
495 			.Add(fProxyPasswordControl->CreateTextViewLayoutItem(), 1, 1)
496 		)
497 		.Add(BSpaceLayoutItem::CreateGlue())
498 
499 		.SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING,
500 			B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING)
501 
502 		.TopView()
503 	;
504 	view->SetName(B_TRANSLATE("Proxy server"));
505 	return view;
506 }
507 
508 
509 void
510 SettingsWindow::_BuildSizesMenu(BMenu* menu, uint32 messageWhat)
511 {
512 	const float kMinSize = 8.0;
513 	const float kMaxSize = 18.0;
514 
515 	const int32 kSizes[] = {7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 21, 24, 0};
516 
517 	for (int32 i = 0; kSizes[i]; i++) {
518 		int32 size = kSizes[i];
519 		if (size < kMinSize || size > kMaxSize)
520 			continue;
521 
522 		char label[32];
523 		snprintf(label, sizeof(label), "%" B_PRId32, size);
524 
525 		BMessage* message = new BMessage(messageWhat);
526 		message->AddInt32("size", size);
527 
528 		BMenuItem* item = new BMenuItem(label, message);
529 
530 		menu->AddItem(item);
531 		item->SetTarget(this);
532 	}
533 }
534 
535 
536 void
537 SettingsWindow::_SetupFontSelectionView(FontSelectionView* view,
538 	BMessage* message)
539 {
540 	AddHandler(view);
541 	view->AttachedToLooper();
542 	view->SetMessage(message);
543 	view->SetTarget(this);
544 }
545 
546 
547 // #pragma mark -
548 
549 
550 bool
551 SettingsWindow::_CanApplySettings() const
552 {
553 	bool canApply = false;
554 
555 	// General settings
556 	canApply = canApply || (strcmp(fStartPageControl->Text(),
557 		fSettings->GetValue(kSettingsKeyStartPageURL,
558 			kDefaultStartPageURL)) != 0);
559 
560 	canApply = canApply || (strcmp(fSearchPageControl->Text(),
561 		fSettings->GetValue(kSettingsKeySearchPageURL,
562 			kDefaultSearchPageURL)) != 0);
563 
564 	canApply = canApply || (strcmp(fDownloadFolderControl->Text(),
565 		fSettings->GetValue(kSettingsKeyDownloadPath,
566 			kDefaultDownloadPath)) != 0);
567 
568 	canApply = canApply || ((fShowTabsIfOnlyOnePage->Value() == B_CONTROL_ON)
569 		!= fSettings->GetValue(kSettingsKeyShowTabsIfSinglePageOpen, true));
570 
571 	canApply = canApply || (
572 		(fAutoHideInterfaceInFullscreenMode->Value() == B_CONTROL_ON)
573 		!= fSettings->GetValue(kSettingsKeyAutoHideInterfaceInFullscreenMode,
574 			false));
575 
576 	canApply = canApply || (
577 		(fAutoHidePointer->Value() == B_CONTROL_ON)
578 		!= fSettings->GetValue(kSettingsKeyAutoHidePointer, false));
579 
580 	canApply = canApply || ((fShowHomeButton->Value() == B_CONTROL_ON)
581 		!= fSettings->GetValue(kSettingsKeyShowHomeButton, true));
582 
583 	canApply = canApply || (fDaysInHistory->Value()
584 		!= BrowsingHistory::DefaultInstance()->MaxHistoryItemAge());
585 
586 	// New window policy
587 	canApply = canApply || (_NewWindowPolicy()
588 		!= fSettings->GetValue(kSettingsKeyNewWindowPolicy,
589 			(uint32)OpenStartPage));
590 
591 	// New tab policy
592 	canApply = canApply || (_NewTabPolicy()
593 		!= fSettings->GetValue(kSettingsKeyNewTabPolicy,
594 			(uint32)OpenBlankPage));
595 
596 	// Font settings
597 	canApply = canApply || (fStandardFontView->Font()
598 		!= fSettings->GetValue("standard font", *be_plain_font));
599 
600 	canApply = canApply || (fSerifFontView->Font()
601 		!= fSettings->GetValue("serif font", _FindDefaultSerifFont()));
602 
603 	canApply = canApply || (fSansSerifFontView->Font()
604 		!= fSettings->GetValue("sans serif font", *be_plain_font));
605 
606 	canApply = canApply || (fFixedFontView->Font()
607 		!= fSettings->GetValue("fixed font", *be_fixed_font));
608 
609 	canApply = canApply || (_SizesMenuValue(fStandardSizesMenu->Menu())
610 		!= fSettings->GetValue("standard font size", kDefaultFontSize));
611 
612 	canApply = canApply || (_SizesMenuValue(fFixedSizesMenu->Menu())
613 		!= fSettings->GetValue("fixed font size", kDefaultFontSize));
614 
615 	// Proxy settings
616 	canApply = canApply || ((fUseProxyCheckBox->Value() == B_CONTROL_ON)
617 		!= fSettings->GetValue(kSettingsKeyUseProxy, false));
618 
619 	canApply = canApply || (strcmp(fProxyAddressControl->Text(),
620 		fSettings->GetValue(kSettingsKeyProxyAddress, "")) != 0);
621 
622 	canApply = canApply || (_ProxyPort()
623 		!= fSettings->GetValue(kSettingsKeyProxyPort, (uint32)0));
624 
625 	canApply = canApply || ((fUseProxyAuthCheckBox->Value() == B_CONTROL_ON)
626 		!= fSettings->GetValue(kSettingsKeyUseProxyAuth, false));
627 
628 	canApply = canApply || (strcmp(fProxyUsernameControl->Text(),
629 		fSettings->GetValue(kSettingsKeyProxyUsername, "")) != 0);
630 
631 	canApply = canApply || (strcmp(fProxyPasswordControl->Text(),
632 		fSettings->GetValue(kSettingsKeyProxyPassword, "")) != 0);
633 
634 	return canApply;
635 }
636 
637 
638 void
639 SettingsWindow::_ApplySettings()
640 {
641 	// Store general settings
642 	BrowsingHistory::DefaultInstance()->SetMaxHistoryItemAge(
643 		(uint32)fDaysInHistory->Value());
644 	fSettings->SetValue(kSettingsKeyStartPageURL, fStartPageControl->Text());
645 	fSettings->SetValue(kSettingsKeySearchPageURL, fSearchPageControl->Text());
646 	fSettings->SetValue(kSettingsKeyDownloadPath, fDownloadFolderControl->Text());
647 	fSettings->SetValue(kSettingsKeyShowTabsIfSinglePageOpen,
648 		fShowTabsIfOnlyOnePage->Value() == B_CONTROL_ON);
649 	fSettings->SetValue(kSettingsKeyAutoHideInterfaceInFullscreenMode,
650 		fAutoHideInterfaceInFullscreenMode->Value() == B_CONTROL_ON);
651 	fSettings->SetValue(kSettingsKeyAutoHidePointer,
652 		fAutoHidePointer->Value() == B_CONTROL_ON);
653 	fSettings->SetValue(kSettingsKeyShowHomeButton,
654 		fShowHomeButton->Value() == B_CONTROL_ON);
655 
656 	// New page policies
657 	fSettings->SetValue(kSettingsKeyNewWindowPolicy, _NewWindowPolicy());
658 	fSettings->SetValue(kSettingsKeyNewTabPolicy, _NewTabPolicy());
659 
660 	// Store fond settings
661 	fSettings->SetValue("standard font", fStandardFontView->Font());
662 	fSettings->SetValue("serif font", fSerifFontView->Font());
663 	fSettings->SetValue("sans serif font", fSansSerifFontView->Font());
664 	fSettings->SetValue("fixed font", fFixedFontView->Font());
665 	int32 standardFontSize = _SizesMenuValue(fStandardSizesMenu->Menu());
666 	int32 fixedFontSize = _SizesMenuValue(fFixedSizesMenu->Menu());
667 	fSettings->SetValue("standard font size", standardFontSize);
668 	fSettings->SetValue("fixed font size", fixedFontSize);
669 
670 	// Store proxy settings
671 
672 	fSettings->SetValue(kSettingsKeyUseProxy,
673 		fUseProxyCheckBox->Value() == B_CONTROL_ON);
674 	fSettings->SetValue(kSettingsKeyProxyAddress,
675 		fProxyAddressControl->Text());
676 	uint32 proxyPort = _ProxyPort();
677 	fSettings->SetValue(kSettingsKeyProxyPort, proxyPort);
678 	fSettings->SetValue(kSettingsKeyUseProxyAuth,
679 		fUseProxyAuthCheckBox->Value() == B_CONTROL_ON);
680 	fSettings->SetValue(kSettingsKeyProxyUsername,
681 		fProxyUsernameControl->Text());
682 	fSettings->SetValue(kSettingsKeyProxyPassword,
683 		fProxyPasswordControl->Text());
684 
685 	fSettings->Save();
686 
687 	// Apply settings to default web page settings.
688 	BWebSettings::Default()->SetStandardFont(fStandardFontView->Font());
689 	BWebSettings::Default()->SetSerifFont(fSerifFontView->Font());
690 	BWebSettings::Default()->SetSansSerifFont(fSansSerifFontView->Font());
691 	BWebSettings::Default()->SetFixedFont(fFixedFontView->Font());
692 	BWebSettings::Default()->SetDefaultStandardFontSize(standardFontSize);
693 	BWebSettings::Default()->SetDefaultFixedFontSize(fixedFontSize);
694 
695 	if (fUseProxyCheckBox->Value() == B_CONTROL_ON) {
696 		if (fUseProxyAuthCheckBox->Value() == B_CONTROL_ON) {
697 			BWebSettings::Default()->SetProxyInfo(fProxyAddressControl->Text(),
698 				proxyPort, B_PROXY_TYPE_HTTP, fProxyUsernameControl->Text(),
699 				fProxyPasswordControl->Text());
700 		} else {
701 			BWebSettings::Default()->SetProxyInfo(fProxyAddressControl->Text(),
702 				proxyPort, B_PROXY_TYPE_HTTP, "", "");
703 		}
704 	} else
705 		BWebSettings::Default()->SetProxyInfo();
706 
707 	// This will find all currently instantiated page settings and apply
708 	// the default values, unless the page settings have local overrides.
709 	BWebSettings::Default()->Apply();
710 
711 	_ValidateControlsEnabledStatus();
712 }
713 
714 
715 void
716 SettingsWindow::_RevertSettings()
717 {
718 	fStartPageControl->SetText(
719 		fSettings->GetValue(kSettingsKeyStartPageURL, kDefaultStartPageURL));
720 
721 	fSearchPageControl->SetText(
722 		fSettings->GetValue(kSettingsKeySearchPageURL, kDefaultSearchPageURL));
723 
724 	fDownloadFolderControl->SetText(
725 		fSettings->GetValue(kSettingsKeyDownloadPath, kDefaultDownloadPath));
726 	fShowTabsIfOnlyOnePage->SetValue(
727 		fSettings->GetValue(kSettingsKeyShowTabsIfSinglePageOpen, true));
728 	fAutoHideInterfaceInFullscreenMode->SetValue(
729 		fSettings->GetValue(kSettingsKeyAutoHideInterfaceInFullscreenMode,
730 			false));
731 	fAutoHidePointer->SetValue(
732 		fSettings->GetValue(kSettingsKeyAutoHidePointer, false));
733 	fShowHomeButton->SetValue(
734 		fSettings->GetValue(kSettingsKeyShowHomeButton, true));
735 
736 	fDaysInHistory->SetValue(
737 		BrowsingHistory::DefaultInstance()->MaxHistoryItemAge());
738 
739 	// New window policy
740 	uint32 newWindowPolicy = fSettings->GetValue(kSettingsKeyNewWindowPolicy,
741 		(uint32)OpenStartPage);
742 	switch (newWindowPolicy) {
743 		default:
744 		case OpenStartPage:
745 			fNewWindowBehaviorOpenHomeItem->SetMarked(true);
746 			break;
747 		case OpenSearchPage:
748 			fNewWindowBehaviorOpenSearchItem->SetMarked(true);
749 			break;
750 		case OpenBlankPage:
751 			fNewWindowBehaviorOpenBlankItem->SetMarked(true);
752 			break;
753 	}
754 
755 	// New tab policy
756 	uint32 newTabPolicy = fSettings->GetValue(kSettingsKeyNewTabPolicy,
757 		(uint32)OpenBlankPage);
758 	switch (newTabPolicy) {
759 		default:
760 		case OpenBlankPage:
761 			fNewTabBehaviorOpenBlankItem->SetMarked(true);
762 			break;
763 		case OpenStartPage:
764 			fNewTabBehaviorOpenHomeItem->SetMarked(true);
765 			break;
766 		case OpenSearchPage:
767 			fNewTabBehaviorOpenSearchItem->SetMarked(true);
768 			break;
769 		case CloneCurrentPage:
770 			fNewTabBehaviorCloneCurrentItem->SetMarked(true);
771 			break;
772 	}
773 
774 	// Font settings
775 	int32 defaultFontSize = fSettings->GetValue("standard font size",
776 		kDefaultFontSize);
777 	int32 defaultFixedFontSize = fSettings->GetValue("fixed font size",
778 		kDefaultFontSize);
779 
780 	_SetSizesMenuValue(fStandardSizesMenu->Menu(), defaultFontSize);
781 	_SetSizesMenuValue(fFixedSizesMenu->Menu(), defaultFixedFontSize);
782 
783 	fStandardFontView->SetFont(fSettings->GetValue("standard font",
784 		*be_plain_font), defaultFontSize);
785 	fSerifFontView->SetFont(fSettings->GetValue("serif font",
786 		_FindDefaultSerifFont()), defaultFontSize);
787 	fSansSerifFontView->SetFont(fSettings->GetValue("sans serif font",
788 		*be_plain_font), defaultFontSize);
789 	fFixedFontView->SetFont(fSettings->GetValue("fixed font",
790 		*be_fixed_font), defaultFixedFontSize);
791 
792 	// Proxy settings
793 	fUseProxyCheckBox->SetValue(fSettings->GetValue(kSettingsKeyUseProxy,
794 		false));
795 	fProxyAddressControl->SetText(fSettings->GetValue(kSettingsKeyProxyAddress,
796 		""));
797 	BString keyProxyPort;
798 	keyProxyPort << fSettings->GetValue(kSettingsKeyProxyPort, (uint32)0);
799 	fProxyPortControl->SetText(keyProxyPort.String());
800 	fUseProxyAuthCheckBox->SetValue(fSettings->GetValue(kSettingsKeyUseProxyAuth,
801 		false));
802 	fProxyUsernameControl->SetText(fSettings->GetValue(kSettingsKeyProxyUsername,
803 		""));
804 	fProxyPasswordControl->SetText(fSettings->GetValue(kSettingsKeyProxyPassword,
805 		""));
806 
807 	_ValidateControlsEnabledStatus();
808 }
809 
810 
811 void
812 SettingsWindow::_ValidateControlsEnabledStatus()
813 {
814 	bool canApply = _CanApplySettings();
815 	fApplyButton->SetEnabled(canApply);
816 	fRevertButton->SetEnabled(canApply);
817 	// Let the Cancel button be enabled always, as another way to close the
818 	// window...
819 	fCancelButton->SetEnabled(true);
820 
821 	bool useProxy = fUseProxyCheckBox->Value() == B_CONTROL_ON;
822 	fProxyAddressControl->SetEnabled(useProxy);
823 	fProxyPortControl->SetEnabled(useProxy);
824 	fUseProxyAuthCheckBox->SetEnabled(useProxy);
825 	bool useProxyAuth = useProxy && fUseProxyAuthCheckBox->Value() == B_CONTROL_ON;
826 	fProxyUsernameControl->SetEnabled(useProxyAuth);
827 	fProxyPasswordControl->SetEnabled(useProxyAuth);
828 }
829 
830 
831 // #pragma mark -
832 
833 
834 uint32
835 SettingsWindow::_NewWindowPolicy() const
836 {
837 	uint32 newWindowPolicy = OpenStartPage;
838 	BMenuItem* markedItem = fNewWindowBehaviorMenu->Menu()->FindMarked();
839 	if (markedItem == fNewWindowBehaviorOpenSearchItem)
840 		newWindowPolicy = OpenSearchPage;
841 	else if (markedItem == fNewWindowBehaviorOpenBlankItem)
842 		newWindowPolicy = OpenBlankPage;
843 	return newWindowPolicy;
844 }
845 
846 
847 uint32
848 SettingsWindow::_NewTabPolicy() const
849 {
850 	uint32 newTabPolicy = OpenBlankPage;
851 	BMenuItem* markedItem = fNewTabBehaviorMenu->Menu()->FindMarked();
852 	if (markedItem == fNewTabBehaviorCloneCurrentItem)
853 		newTabPolicy = CloneCurrentPage;
854 	else if (markedItem == fNewTabBehaviorOpenHomeItem)
855 		newTabPolicy = OpenStartPage;
856 	else if (markedItem == fNewTabBehaviorOpenSearchItem)
857 		newTabPolicy = OpenSearchPage;
858 	return newTabPolicy;
859 }
860 
861 
862 void
863 SettingsWindow::_SetSizesMenuValue(BMenu* menu, int32 value)
864 {
865 	for (int32 i = 0; BMenuItem* item = menu->ItemAt(i); i++) {
866 		bool marked = false;
867 		if (BMessage* message = item->Message()) {
868 			int32 size;
869 			if (message->FindInt32("size", &size) == B_OK && size == value)
870 				marked = true;
871 		}
872 		item->SetMarked(marked);
873 	}
874 }
875 
876 
877 int32
878 SettingsWindow::_SizesMenuValue(BMenu* menu) const
879 {
880 	if (BMenuItem* item = menu->FindMarked()) {
881 		if (BMessage* message = item->Message()) {
882 			int32 size;
883 			if (message->FindInt32("size", &size) == B_OK)
884 				return size;
885 		}
886 	}
887 	return kDefaultFontSize;
888 }
889 
890 
891 BFont
892 SettingsWindow::_FindDefaultSerifFont() const
893 {
894 	// Default to the first "serif" font we find.
895 	BFont serifFont(*be_plain_font);
896 	font_family family;
897 	int32 familyCount = count_font_families();
898 	for (int32 i = 0; i < familyCount; i++) {
899 		if (get_font_family(i, &family) == B_OK) {
900 			BString familyString(family);
901 			if (familyString.IFindFirst("sans") >= 0)
902 				continue;
903 			if (familyString.IFindFirst("serif") >= 0) {
904 				serifFont.SetFamilyAndFace(family, B_REGULAR_FACE);
905 				break;
906 			}
907 		}
908 	}
909 	return serifFont;
910 }
911 
912 
913 uint32
914 SettingsWindow::_ProxyPort() const
915 {
916 	return atoul(fProxyPortControl->Text());
917 }
918 
919 
920