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