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