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