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