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