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