xref: /haiku/src/apps/webpositive/SettingsWindow.cpp (revision 2b76973fa2401f7a5edf68e6470f3d3210cbcff3)
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 	fSearchPageControl->SetText(
249 		fSettings->GetValue(kSettingsKeySearchPageURL, kDefaultSearchPageURL));
250 
251 	fDownloadFolderControl = new BTextControl("download folder",
252 		B_TRANSLATE("Download folder:"), "",
253 		new BMessage(MSG_DOWNLOAD_FOLDER_CHANGED));
254 	fDownloadFolderControl->SetModificationMessage(
255 		new BMessage(MSG_DOWNLOAD_FOLDER_CHANGED));
256 	fDownloadFolderControl->SetText(
257 		fSettings->GetValue(kSettingsKeyDownloadPath, kDefaultDownloadPath));
258 
259 	fNewWindowBehaviorOpenHomeItem = new BMenuItem(
260 		B_TRANSLATE("Open start page"),
261 		new BMessage(MSG_NEW_WINDOWS_BEHAVIOR_CHANGED));
262 	fNewWindowBehaviorOpenSearchItem = new BMenuItem(
263 		B_TRANSLATE("Open search page"),
264 		new BMessage(MSG_NEW_WINDOWS_BEHAVIOR_CHANGED));
265 	fNewWindowBehaviorOpenBlankItem = new BMenuItem(
266 		B_TRANSLATE("Open blank page"),
267 		new BMessage(MSG_NEW_WINDOWS_BEHAVIOR_CHANGED));
268 
269 	fNewTabBehaviorCloneCurrentItem = new BMenuItem(
270 		B_TRANSLATE("Clone current page"),
271 		new BMessage(MSG_NEW_TABS_BEHAVIOR_CHANGED));
272 	fNewTabBehaviorOpenHomeItem = new BMenuItem(
273 		B_TRANSLATE("Open start page"),
274 		new BMessage(MSG_NEW_TABS_BEHAVIOR_CHANGED));
275 	fNewTabBehaviorOpenSearchItem = new BMenuItem(
276 		B_TRANSLATE("Open search page"),
277 		new BMessage(MSG_NEW_TABS_BEHAVIOR_CHANGED));
278 	fNewTabBehaviorOpenBlankItem = new BMenuItem(
279 		B_TRANSLATE("Open blank page"),
280 		new BMessage(MSG_NEW_TABS_BEHAVIOR_CHANGED));
281 
282 	fNewWindowBehaviorOpenHomeItem->SetMarked(true);
283 	fNewTabBehaviorOpenBlankItem->SetMarked(true);
284 
285 	BPopUpMenu* newWindowBehaviorMenu = new BPopUpMenu("New windows");
286 	newWindowBehaviorMenu->AddItem(fNewWindowBehaviorOpenHomeItem);
287 	newWindowBehaviorMenu->AddItem(fNewWindowBehaviorOpenSearchItem);
288 	newWindowBehaviorMenu->AddItem(fNewWindowBehaviorOpenBlankItem);
289 	fNewWindowBehaviorMenu = new BMenuField("new window behavior",
290 		B_TRANSLATE("New windows:"), newWindowBehaviorMenu);
291 
292 	BPopUpMenu* newTabBehaviorMenu = new BPopUpMenu("New tabs");
293 	newTabBehaviorMenu->AddItem(fNewTabBehaviorOpenBlankItem);
294 	newTabBehaviorMenu->AddItem(fNewTabBehaviorOpenHomeItem);
295 	newTabBehaviorMenu->AddItem(fNewTabBehaviorOpenSearchItem);
296 	newTabBehaviorMenu->AddItem(fNewTabBehaviorCloneCurrentItem);
297 	fNewTabBehaviorMenu = new BMenuField("new tab behavior",
298 		B_TRANSLATE("New tabs:"), newTabBehaviorMenu);
299 
300 	fDaysInHistoryMenuControl = new BTextControl("days in history",
301 		B_TRANSLATE("Number of days to keep links in History menu:"), "",
302 		new BMessage(MSG_HISTORY_MENU_DAYS_CHANGED));
303 	fDaysInHistoryMenuControl->SetModificationMessage(
304 		new BMessage(MSG_HISTORY_MENU_DAYS_CHANGED));
305 	BString maxHistoryAge;
306 	maxHistoryAge << BrowsingHistory::DefaultInstance()->MaxHistoryItemAge();
307 	fDaysInHistoryMenuControl->SetText(maxHistoryAge.String());
308 	for (uchar i = 0; i < '0'; i++)
309 		fDaysInHistoryMenuControl->TextView()->DisallowChar(i);
310 	for (uchar i = '9' + 1; i <= 128; i++)
311 		fDaysInHistoryMenuControl->TextView()->DisallowChar(i);
312 
313 	fShowTabsIfOnlyOnePage = new BCheckBox("show tabs if only one page",
314 		B_TRANSLATE("Show tabs if only one page is open"),
315 		new BMessage(MSG_TAB_DISPLAY_BEHAVIOR_CHANGED));
316 	fShowTabsIfOnlyOnePage->SetValue(B_CONTROL_ON);
317 
318 	fAutoHideInterfaceInFullscreenMode = new BCheckBox("auto-hide interface",
319 		B_TRANSLATE("Auto-hide interface in full screen mode"),
320 		new BMessage(MSG_AUTO_HIDE_INTERFACE_BEHAVIOR_CHANGED));
321 	fAutoHideInterfaceInFullscreenMode->SetValue(B_CONTROL_OFF);
322 
323 	fAutoHidePointer = new BCheckBox("auto-hide pointer",
324 		B_TRANSLATE("Auto-hide mouse pointer"),
325 		new BMessage(MSG_AUTO_HIDE_POINTER_BEHAVIOR_CHANGED));
326 	fAutoHidePointer->SetValue(B_CONTROL_OFF);
327 
328 	fShowHomeButton = new BCheckBox("show home button",
329 		B_TRANSLATE("Show home button"),
330 		new BMessage(MSG_SHOW_HOME_BUTTON_CHANGED));
331 	fShowHomeButton->SetValue(B_CONTROL_ON);
332 
333 	BView* view = BGroupLayoutBuilder(B_VERTICAL, spacing / 2)
334 		.Add(BGridLayoutBuilder(spacing / 2, spacing / 2)
335 			.Add(fStartPageControl->CreateLabelLayoutItem(), 0, 0)
336 			.Add(fStartPageControl->CreateTextViewLayoutItem(), 1, 0)
337 
338 			.Add(fSearchPageControl->CreateLabelLayoutItem(), 0, 1)
339 			.Add(fSearchPageControl->CreateTextViewLayoutItem(), 1, 1)
340 
341 			.Add(fDownloadFolderControl->CreateLabelLayoutItem(), 0, 2)
342 			.Add(fDownloadFolderControl->CreateTextViewLayoutItem(), 1, 2)
343 
344 			.Add(fNewWindowBehaviorMenu->CreateLabelLayoutItem(), 0, 3)
345 			.Add(fNewWindowBehaviorMenu->CreateMenuBarLayoutItem(), 1, 3)
346 
347 			.Add(fNewTabBehaviorMenu->CreateLabelLayoutItem(), 0, 4)
348 			.Add(fNewTabBehaviorMenu->CreateMenuBarLayoutItem(), 1, 4)
349 		)
350 		.Add(BSpaceLayoutItem::CreateHorizontalStrut(spacing))
351 		.Add(new BSeparatorView(B_HORIZONTAL, B_PLAIN_BORDER))
352 		.Add(BSpaceLayoutItem::CreateHorizontalStrut(spacing))
353 		.Add(fShowTabsIfOnlyOnePage)
354 		.Add(fAutoHideInterfaceInFullscreenMode)
355 		.Add(fAutoHidePointer)
356 		.Add(fShowHomeButton)
357 		.Add(fDaysInHistoryMenuControl)
358 		.Add(BSpaceLayoutItem::CreateHorizontalStrut(spacing))
359 
360 		.SetInsets(spacing, spacing, spacing, spacing)
361 
362 		.TopView()
363 	;
364 	view->SetName(B_TRANSLATE("General"));
365 	return view;
366 }
367 
368 
369 BView*
370 SettingsWindow::_CreateFontsPage(float spacing)
371 {
372 	fStandardFontView = new FontSelectionView("standard",
373 		B_TRANSLATE("Standard font:"), true, be_plain_font);
374 	BFont defaultSerifFont = _FindDefaultSerifFont();
375 	fSerifFontView = new FontSelectionView("serif",
376 		B_TRANSLATE("Serif font:"), true, &defaultSerifFont);
377 	fSansSerifFontView = new FontSelectionView("sans serif",
378 		B_TRANSLATE("Sans serif font:"), true, be_plain_font);
379 	fFixedFontView = new FontSelectionView("fixed",
380 		B_TRANSLATE("Fixed font:"), true, be_fixed_font);
381 
382 	fStandardSizesMenu =  new BMenuField("standard font size",
383 		B_TRANSLATE("Default standard font size:"), new BPopUpMenu("sizes"),
384 		B_WILL_DRAW);
385 	_BuildSizesMenu(fStandardSizesMenu->Menu(),
386 		MSG_STANDARD_FONT_SIZE_SELECTED);
387 
388 	fFixedSizesMenu =  new BMenuField("fixed font size",
389 		B_TRANSLATE("Default fixed font size:"), new BPopUpMenu("sizes"),
390 		B_WILL_DRAW);
391 	_BuildSizesMenu(fFixedSizesMenu->Menu(), MSG_FIXED_FONT_SIZE_SELECTED);
392 
393 	BView* view = BGridLayoutBuilder(spacing / 2, spacing / 2)
394 		.Add(fStandardFontView->CreateFontsLabelLayoutItem(), 0, 0)
395 		.Add(fStandardFontView->CreateFontsMenuBarLayoutItem(), 1, 0)
396 		.Add(fStandardFontView->PreviewBox(), 0, 1, 2)
397 		.Add(BSpaceLayoutItem::CreateHorizontalStrut(spacing), 0, 2, 2)
398 
399 		.Add(fSerifFontView->CreateFontsLabelLayoutItem(), 0, 3)
400 		.Add(fSerifFontView->CreateFontsMenuBarLayoutItem(), 1, 3)
401 		.Add(fSerifFontView->PreviewBox(), 0, 4, 2)
402 		.Add(BSpaceLayoutItem::CreateHorizontalStrut(spacing), 0, 5, 2)
403 
404 		.Add(fSansSerifFontView->CreateFontsLabelLayoutItem(), 0, 6)
405 		.Add(fSansSerifFontView->CreateFontsMenuBarLayoutItem(), 1, 6)
406 		.Add(fSansSerifFontView->PreviewBox(), 0, 7, 2)
407 		.Add(BSpaceLayoutItem::CreateHorizontalStrut(spacing), 0, 8, 2)
408 
409 		.Add(fFixedFontView->CreateFontsLabelLayoutItem(), 0, 9)
410 		.Add(fFixedFontView->CreateFontsMenuBarLayoutItem(), 1, 9)
411 		.Add(fFixedFontView->PreviewBox(), 0, 10, 2)
412 		.Add(BSpaceLayoutItem::CreateHorizontalStrut(spacing), 0, 11, 2)
413 
414 		.Add(fStandardSizesMenu->CreateLabelLayoutItem(), 0, 12)
415 		.Add(fStandardSizesMenu->CreateMenuBarLayoutItem(), 1, 12)
416 		.Add(fFixedSizesMenu->CreateLabelLayoutItem(), 0, 13)
417 		.Add(fFixedSizesMenu->CreateMenuBarLayoutItem(), 1, 13)
418 
419 		.SetInsets(spacing, spacing, spacing, spacing)
420 
421 		.View()
422 	;
423 
424 	view->SetName(B_TRANSLATE("Fonts"));
425 	return view;
426 }
427 
428 
429 BView*
430 SettingsWindow::_CreateProxyPage(float spacing)
431 {
432 	fUseProxyCheckBox = new BCheckBox("use proxy",
433 		B_TRANSLATE("Use proxy server to connect to the internet"),
434 		new BMessage(MSG_USE_PROXY_CHANGED));
435 	fUseProxyCheckBox->SetValue(B_CONTROL_ON);
436 
437 	fProxyAddressControl = new BTextControl("proxy address",
438 		B_TRANSLATE("Proxy server address:"), "",
439 		new BMessage(MSG_PROXY_ADDRESS_CHANGED));
440 	fProxyAddressControl->SetModificationMessage(
441 		new BMessage(MSG_PROXY_ADDRESS_CHANGED));
442 	fProxyAddressControl->SetText(
443 		fSettings->GetValue(kSettingsKeyProxyAddress, ""));
444 
445 	fProxyPortControl = new BTextControl("proxy port",
446 		B_TRANSLATE("Proxy server port:"), "",
447 		new BMessage(MSG_PROXY_PORT_CHANGED));
448 	fProxyPortControl->SetModificationMessage(
449 		new BMessage(MSG_PROXY_PORT_CHANGED));
450 	fProxyPortControl->SetText(
451 		fSettings->GetValue(kSettingsKeyProxyAddress, ""));
452 
453 	fUseProxyAuthCheckBox = new BCheckBox("use authentication",
454 		B_TRANSLATE("Proxy server requires authentication"),
455 		new BMessage(MSG_USE_PROXY_AUTH_CHANGED));
456 	fUseProxyAuthCheckBox->SetValue(B_CONTROL_ON);
457 
458 	fProxyUsernameControl = new BTextControl("proxy username",
459 		B_TRANSLATE("Proxy username:"), "",
460 		new BMessage(MSG_PROXY_USERNAME_CHANGED));
461 	fProxyUsernameControl->SetModificationMessage(
462 		new BMessage(MSG_PROXY_USERNAME_CHANGED));
463 	fProxyUsernameControl->SetText(
464 		fSettings->GetValue(kSettingsKeyProxyUsername, ""));
465 
466 	fProxyPasswordControl = new BTextControl("proxy password",
467 		B_TRANSLATE("Proxy password:"), "",
468 		new BMessage(MSG_PROXY_PASSWORD_CHANGED));
469 	fProxyPasswordControl->SetModificationMessage(
470 		new BMessage(MSG_PROXY_PASSWORD_CHANGED));
471 	fProxyPasswordControl->TextView()->HideTyping(true);
472 	fProxyPasswordControl->SetText(
473 		fSettings->GetValue(kSettingsKeyProxyPassword, ""));
474 
475 	BView* view = BGroupLayoutBuilder(B_VERTICAL, spacing / 2)
476 		.Add(fUseProxyCheckBox)
477 		.Add(BGridLayoutBuilder(spacing / 2, spacing / 2)
478 			.Add(fProxyAddressControl->CreateLabelLayoutItem(), 0, 0)
479 			.Add(fProxyAddressControl->CreateTextViewLayoutItem(), 1, 0)
480 
481 			.Add(fProxyPortControl->CreateLabelLayoutItem(), 0, 1)
482 			.Add(fProxyPortControl->CreateTextViewLayoutItem(), 1, 1)
483 		)
484 		.Add(fUseProxyAuthCheckBox)
485 		.Add(BGridLayoutBuilder(spacing / 2, spacing / 2)
486 			.Add(fProxyUsernameControl->CreateLabelLayoutItem(), 0, 0)
487 			.Add(fProxyUsernameControl->CreateTextViewLayoutItem(), 1, 0)
488 
489 			.Add(fProxyPasswordControl->CreateLabelLayoutItem(), 0, 1)
490 			.Add(fProxyPasswordControl->CreateTextViewLayoutItem(), 1, 1)
491 		)
492 		.Add(BSpaceLayoutItem::CreateGlue())
493 
494 		.SetInsets(spacing, spacing, spacing, spacing)
495 
496 		.TopView()
497 	;
498 	view->SetName(B_TRANSLATE("Proxy server"));
499 	return view;
500 }
501 
502 
503 void
504 SettingsWindow::_BuildSizesMenu(BMenu* menu, uint32 messageWhat)
505 {
506 	const float kMinSize = 8.0;
507 	const float kMaxSize = 18.0;
508 
509 	const int32 kSizes[] = {7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 21, 24, 0};
510 
511 	for (int32 i = 0; kSizes[i]; i++) {
512 		int32 size = kSizes[i];
513 		if (size < kMinSize || size > kMaxSize)
514 			continue;
515 
516 		char label[32];
517 		snprintf(label, sizeof(label), "%" B_PRId32, size);
518 
519 		BMessage* message = new BMessage(messageWhat);
520 		message->AddInt32("size", size);
521 
522 		BMenuItem* item = new BMenuItem(label, message);
523 
524 		menu->AddItem(item);
525 		item->SetTarget(this);
526 	}
527 }
528 
529 
530 void
531 SettingsWindow::_SetupFontSelectionView(FontSelectionView* view,
532 	BMessage* message)
533 {
534 	AddHandler(view);
535 	view->AttachedToLooper();
536 	view->SetMessage(message);
537 	view->SetTarget(this);
538 }
539 
540 
541 // #pragma mark -
542 
543 
544 bool
545 SettingsWindow::_CanApplySettings() const
546 {
547 	bool canApply = false;
548 
549 	// General settings
550 	canApply = canApply || (strcmp(fStartPageControl->Text(),
551 		fSettings->GetValue(kSettingsKeyStartPageURL,
552 			kDefaultStartPageURL)) != 0);
553 
554 	canApply = canApply || (strcmp(fSearchPageControl->Text(),
555 		fSettings->GetValue(kSettingsKeySearchPageURL,
556 			kDefaultSearchPageURL)) != 0);
557 
558 	canApply = canApply || (strcmp(fDownloadFolderControl->Text(),
559 		fSettings->GetValue(kSettingsKeyDownloadPath,
560 			kDefaultDownloadPath)) != 0);
561 
562 	canApply = canApply || ((fShowTabsIfOnlyOnePage->Value() == B_CONTROL_ON)
563 		!= fSettings->GetValue(kSettingsKeyShowTabsIfSinglePageOpen, true));
564 
565 	canApply = canApply || (
566 		(fAutoHideInterfaceInFullscreenMode->Value() == B_CONTROL_ON)
567 		!= fSettings->GetValue(kSettingsKeyAutoHideInterfaceInFullscreenMode,
568 			false));
569 
570 	canApply = canApply || (
571 		(fAutoHidePointer->Value() == B_CONTROL_ON)
572 		!= fSettings->GetValue(kSettingsKeyAutoHidePointer, false));
573 
574 	canApply = canApply || ((fShowHomeButton->Value() == B_CONTROL_ON)
575 		!= fSettings->GetValue(kSettingsKeyShowHomeButton, true));
576 
577 	canApply = canApply || (_MaxHistoryAge()
578 		!= BrowsingHistory::DefaultInstance()->MaxHistoryItemAge());
579 
580 	// New window policy
581 	canApply = canApply || (_NewWindowPolicy()
582 		!= fSettings->GetValue(kSettingsKeyNewWindowPolicy,
583 			(uint32)OpenStartPage));
584 
585 	// New tab policy
586 	canApply = canApply || (_NewTabPolicy()
587 		!= fSettings->GetValue(kSettingsKeyNewTabPolicy,
588 			(uint32)OpenBlankPage));
589 
590 	// Font settings
591 	canApply = canApply || (fStandardFontView->Font()
592 		!= fSettings->GetValue("standard font", *be_plain_font));
593 
594 	canApply = canApply || (fSerifFontView->Font()
595 		!= fSettings->GetValue("serif font", _FindDefaultSerifFont()));
596 
597 	canApply = canApply || (fSansSerifFontView->Font()
598 		!= fSettings->GetValue("sans serif font", *be_plain_font));
599 
600 	canApply = canApply || (fFixedFontView->Font()
601 		!= fSettings->GetValue("fixed font", *be_fixed_font));
602 
603 	canApply = canApply || (_SizesMenuValue(fStandardSizesMenu->Menu())
604 		!= fSettings->GetValue("standard font size", kDefaultFontSize));
605 
606 	canApply = canApply || (_SizesMenuValue(fFixedSizesMenu->Menu())
607 		!= fSettings->GetValue("fixed font size", kDefaultFontSize));
608 
609 	// Proxy settings
610 	canApply = canApply || ((fUseProxyCheckBox->Value() == B_CONTROL_ON)
611 		!= fSettings->GetValue(kSettingsKeyUseProxy, false));
612 
613 	canApply = canApply || (strcmp(fProxyAddressControl->Text(),
614 		fSettings->GetValue(kSettingsKeyProxyAddress, "")) != 0);
615 
616 	canApply = canApply || (_ProxyPort()
617 		!= fSettings->GetValue(kSettingsKeyProxyPort, (uint32)0));
618 
619 	canApply = canApply || ((fUseProxyAuthCheckBox->Value() == B_CONTROL_ON)
620 		!= fSettings->GetValue(kSettingsKeyUseProxyAuth, false));
621 
622 	canApply = canApply || (strcmp(fProxyUsernameControl->Text(),
623 		fSettings->GetValue(kSettingsKeyProxyUsername, "")) != 0);
624 
625 	canApply = canApply || (strcmp(fProxyPasswordControl->Text(),
626 		fSettings->GetValue(kSettingsKeyProxyPassword, "")) != 0);
627 
628 	return canApply;
629 }
630 
631 
632 void
633 SettingsWindow::_ApplySettings()
634 {
635 	// Store general settings
636 	int32 maxHistoryAge = _MaxHistoryAge();
637 	BString text;
638 	text << maxHistoryAge;
639 	fDaysInHistoryMenuControl->SetText(text.String());
640 	BrowsingHistory::DefaultInstance()->SetMaxHistoryItemAge(maxHistoryAge);
641 
642 	fSettings->SetValue(kSettingsKeyStartPageURL, fStartPageControl->Text());
643 	fSettings->SetValue(kSettingsKeySearchPageURL, fSearchPageControl->Text());
644 	fSettings->SetValue(kSettingsKeyDownloadPath, fDownloadFolderControl->Text());
645 	fSettings->SetValue(kSettingsKeyShowTabsIfSinglePageOpen,
646 		fShowTabsIfOnlyOnePage->Value() == B_CONTROL_ON);
647 	fSettings->SetValue(kSettingsKeyAutoHideInterfaceInFullscreenMode,
648 		fAutoHideInterfaceInFullscreenMode->Value() == B_CONTROL_ON);
649 	fSettings->SetValue(kSettingsKeyAutoHidePointer,
650 		fAutoHidePointer->Value() == B_CONTROL_ON);
651 	fSettings->SetValue(kSettingsKeyShowHomeButton,
652 		fShowHomeButton->Value() == B_CONTROL_ON);
653 
654 	// New page policies
655 	fSettings->SetValue(kSettingsKeyNewWindowPolicy, _NewWindowPolicy());
656 	fSettings->SetValue(kSettingsKeyNewTabPolicy, _NewTabPolicy());
657 
658 	// Store fond settings
659 	fSettings->SetValue("standard font", fStandardFontView->Font());
660 	fSettings->SetValue("serif font", fSerifFontView->Font());
661 	fSettings->SetValue("sans serif font", fSansSerifFontView->Font());
662 	fSettings->SetValue("fixed font", fFixedFontView->Font());
663 	int32 standardFontSize = _SizesMenuValue(fStandardSizesMenu->Menu());
664 	int32 fixedFontSize = _SizesMenuValue(fFixedSizesMenu->Menu());
665 	fSettings->SetValue("standard font size", standardFontSize);
666 	fSettings->SetValue("fixed font size", fixedFontSize);
667 
668 	// Store proxy settings
669 
670 	fSettings->SetValue(kSettingsKeyUseProxy,
671 		fUseProxyCheckBox->Value() == B_CONTROL_ON);
672 	fSettings->SetValue(kSettingsKeyProxyAddress,
673 		fProxyAddressControl->Text());
674 	uint32 proxyPort = _ProxyPort();
675 	fSettings->SetValue(kSettingsKeyProxyPort, proxyPort);
676 	fSettings->SetValue(kSettingsKeyUseProxyAuth,
677 		fUseProxyAuthCheckBox->Value() == B_CONTROL_ON);
678 	fSettings->SetValue(kSettingsKeyProxyUsername,
679 		fProxyUsernameControl->Text());
680 	fSettings->SetValue(kSettingsKeyProxyPassword,
681 		fProxyPasswordControl->Text());
682 
683 	fSettings->Save();
684 
685 	// Apply settings to default web page settings.
686 	BWebSettings::Default()->SetStandardFont(fStandardFontView->Font());
687 	BWebSettings::Default()->SetSerifFont(fSerifFontView->Font());
688 	BWebSettings::Default()->SetSansSerifFont(fSansSerifFontView->Font());
689 	BWebSettings::Default()->SetFixedFont(fFixedFontView->Font());
690 	BWebSettings::Default()->SetDefaultStandardFontSize(standardFontSize);
691 	BWebSettings::Default()->SetDefaultFixedFontSize(fixedFontSize);
692 
693 	if (fUseProxyCheckBox->Value() == B_CONTROL_ON) {
694 		if (fUseProxyAuthCheckBox->Value() == B_CONTROL_ON) {
695 			BWebSettings::Default()->SetProxyInfo(fProxyAddressControl->Text(),
696 				proxyPort, B_PROXY_TYPE_HTTP, fProxyUsernameControl->Text(),
697 				fProxyPasswordControl->Text());
698 		} else {
699 			BWebSettings::Default()->SetProxyInfo(fProxyAddressControl->Text(),
700 				proxyPort, B_PROXY_TYPE_HTTP, "", "");
701 		}
702 	} else
703 		BWebSettings::Default()->SetProxyInfo();
704 
705 	// This will find all currently instantiated page settings and apply
706 	// the default values, unless the page settings have local overrides.
707 	BWebSettings::Default()->Apply();
708 
709 
710 	_ValidateControlsEnabledStatus();
711 }
712 
713 
714 void
715 SettingsWindow::_RevertSettings()
716 {
717 	fStartPageControl->SetText(
718 		fSettings->GetValue(kSettingsKeyStartPageURL, kDefaultStartPageURL));
719 
720 	fSearchPageControl->SetText(
721 		fSettings->GetValue(kSettingsKeySearchPageURL, kDefaultSearchPageURL));
722 
723 	fDownloadFolderControl->SetText(
724 		fSettings->GetValue(kSettingsKeyDownloadPath, kDefaultDownloadPath));
725 	fShowTabsIfOnlyOnePage->SetValue(
726 		fSettings->GetValue(kSettingsKeyShowTabsIfSinglePageOpen, true));
727 	fAutoHideInterfaceInFullscreenMode->SetValue(
728 		fSettings->GetValue(kSettingsKeyAutoHideInterfaceInFullscreenMode,
729 			false));
730 	fAutoHidePointer->SetValue(
731 		fSettings->GetValue(kSettingsKeyAutoHidePointer, false));
732 	fShowHomeButton->SetValue(
733 		fSettings->GetValue(kSettingsKeyShowHomeButton, true));
734 
735 	BString text;
736 	text << BrowsingHistory::DefaultInstance()->MaxHistoryItemAge();
737 	fDaysInHistoryMenuControl->SetText(text.String());
738 
739 	// New window policy
740 	uint32 newWindowPolicy = fSettings->GetValue(kSettingsKeyNewWindowPolicy,
741 		(uint32)OpenStartPage);
742 	switch (newWindowPolicy) {
743 		default:
744 		case OpenStartPage:
745 			fNewWindowBehaviorOpenHomeItem->SetMarked(true);
746 			break;
747 		case OpenSearchPage:
748 			fNewWindowBehaviorOpenSearchItem->SetMarked(true);
749 			break;
750 		case OpenBlankPage:
751 			fNewWindowBehaviorOpenBlankItem->SetMarked(true);
752 			break;
753 	}
754 
755 	// New tab policy
756 	uint32 newTabPolicy = fSettings->GetValue(kSettingsKeyNewTabPolicy,
757 		(uint32)OpenBlankPage);
758 	switch (newTabPolicy) {
759 		default:
760 		case OpenBlankPage:
761 			fNewTabBehaviorOpenBlankItem->SetMarked(true);
762 			break;
763 		case OpenStartPage:
764 			fNewTabBehaviorOpenHomeItem->SetMarked(true);
765 			break;
766 		case OpenSearchPage:
767 			fNewTabBehaviorOpenSearchItem->SetMarked(true);
768 			break;
769 		case CloneCurrentPage:
770 			fNewTabBehaviorCloneCurrentItem->SetMarked(true);
771 			break;
772 	}
773 
774 	// Font settings
775 	int32 defaultFontSize = fSettings->GetValue("standard font size",
776 		kDefaultFontSize);
777 	int32 defaultFixedFontSize = fSettings->GetValue("fixed font size",
778 		kDefaultFontSize);
779 
780 	_SetSizesMenuValue(fStandardSizesMenu->Menu(), defaultFontSize);
781 	_SetSizesMenuValue(fFixedSizesMenu->Menu(), defaultFixedFontSize);
782 
783 	fStandardFontView->SetFont(fSettings->GetValue("standard font",
784 		*be_plain_font), defaultFontSize);
785 	fSerifFontView->SetFont(fSettings->GetValue("serif font",
786 		_FindDefaultSerifFont()), defaultFontSize);
787 	fSansSerifFontView->SetFont(fSettings->GetValue("sans serif font",
788 		*be_plain_font), defaultFontSize);
789 	fFixedFontView->SetFont(fSettings->GetValue("fixed font",
790 		*be_fixed_font), defaultFixedFontSize);
791 
792 	// Proxy settings
793 	fUseProxyCheckBox->SetValue(fSettings->GetValue(kSettingsKeyUseProxy,
794 		false));
795 	fProxyAddressControl->SetText(fSettings->GetValue(kSettingsKeyProxyAddress,
796 		""));
797 	text = "";
798 	text << fSettings->GetValue(kSettingsKeyProxyPort, (uint32)0);
799 	fProxyPortControl->SetText(text.String());
800 	fUseProxyAuthCheckBox->SetValue(fSettings->GetValue(kSettingsKeyUseProxyAuth,
801 		false));
802 	fProxyUsernameControl->SetText(fSettings->GetValue(kSettingsKeyProxyUsername,
803 		""));
804 	fProxyPasswordControl->SetText(fSettings->GetValue(kSettingsKeyProxyPassword,
805 		""));
806 
807 	_ValidateControlsEnabledStatus();
808 }
809 
810 
811 void
812 SettingsWindow::_ValidateControlsEnabledStatus()
813 {
814 	bool canApply = _CanApplySettings();
815 	fApplyButton->SetEnabled(canApply);
816 	fRevertButton->SetEnabled(canApply);
817 	// Let the Cancel button be enabled always, as another way to close the
818 	// window...
819 	fCancelButton->SetEnabled(true);
820 
821 	bool useProxy = fUseProxyCheckBox->Value() == B_CONTROL_ON;
822 	fProxyAddressControl->SetEnabled(useProxy);
823 	fProxyPortControl->SetEnabled(useProxy);
824 	fUseProxyAuthCheckBox->SetEnabled(useProxy);
825 	bool useProxyAuth = useProxy && fUseProxyAuthCheckBox->Value() == B_CONTROL_ON;
826 	fProxyUsernameControl->SetEnabled(useProxyAuth);
827 	fProxyPasswordControl->SetEnabled(useProxyAuth);
828 }
829 
830 
831 // #pragma mark -
832 
833 
834 uint32
835 SettingsWindow::_NewWindowPolicy() const
836 {
837 	uint32 newWindowPolicy = OpenStartPage;
838 	BMenuItem* markedItem = fNewWindowBehaviorMenu->Menu()->FindMarked();
839 	if (markedItem == fNewWindowBehaviorOpenSearchItem)
840 		newWindowPolicy = OpenSearchPage;
841 	else if (markedItem == fNewWindowBehaviorOpenBlankItem)
842 		newWindowPolicy = OpenBlankPage;
843 	return newWindowPolicy;
844 }
845 
846 
847 uint32
848 SettingsWindow::_NewTabPolicy() const
849 {
850 	uint32 newTabPolicy = OpenBlankPage;
851 	BMenuItem* markedItem = fNewTabBehaviorMenu->Menu()->FindMarked();
852 	if (markedItem == fNewTabBehaviorCloneCurrentItem)
853 		newTabPolicy = CloneCurrentPage;
854 	else if (markedItem == fNewTabBehaviorOpenHomeItem)
855 		newTabPolicy = OpenStartPage;
856 	else if (markedItem == fNewTabBehaviorOpenSearchItem)
857 		newTabPolicy = OpenSearchPage;
858 	return newTabPolicy;
859 }
860 
861 
862 int32
863 SettingsWindow::_MaxHistoryAge() const
864 {
865 	int32 maxHistoryAge = atoi(fDaysInHistoryMenuControl->Text());
866 	if (maxHistoryAge <= 0)
867 		maxHistoryAge = 1;
868 	if (maxHistoryAge >= 35)
869 		maxHistoryAge = 35;
870 	return maxHistoryAge;
871 }
872 
873 
874 void
875 SettingsWindow::_SetSizesMenuValue(BMenu* menu, int32 value)
876 {
877 	for (int32 i = 0; BMenuItem* item = menu->ItemAt(i); i++) {
878 		bool marked = false;
879 		if (BMessage* message = item->Message()) {
880 			int32 size;
881 			if (message->FindInt32("size", &size) == B_OK && size == value)
882 				marked = true;
883 		}
884 		item->SetMarked(marked);
885 	}
886 }
887 
888 
889 int32
890 SettingsWindow::_SizesMenuValue(BMenu* menu) const
891 {
892 	if (BMenuItem* item = menu->FindMarked()) {
893 		if (BMessage* message = item->Message()) {
894 			int32 size;
895 			if (message->FindInt32("size", &size) == B_OK)
896 				return size;
897 		}
898 	}
899 	return kDefaultFontSize;
900 }
901 
902 
903 BFont
904 SettingsWindow::_FindDefaultSerifFont() const
905 {
906 	// Default to the first "serif" font we find.
907 	BFont serifFont(*be_plain_font);
908 	font_family family;
909 	int32 familyCount = count_font_families();
910 	for (int32 i = 0; i < familyCount; i++) {
911 		if (get_font_family(i, &family) == B_OK) {
912 			BString familyString(family);
913 			if (familyString.IFindFirst("sans") >= 0)
914 				continue;
915 			if (familyString.IFindFirst("serif") >= 0) {
916 				serifFont.SetFamilyAndFace(family, B_REGULAR_FACE);
917 				break;
918 			}
919 		}
920 	}
921 	return serifFont;
922 }
923 
924 
925 uint32
926 SettingsWindow::_ProxyPort() const
927 {
928 	return atoul(fProxyPortControl->Text());
929 }
930 
931 
932