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