xref: /haiku/src/apps/terminal/PrefWindow.cpp (revision b028e77473189065f2baefc6f5e10d451cf591e2)
1 /*
2  * Copyright 2007, Haiku, Inc.
3  * Copyright 2003-2004 Kian Duffy, myob@users.sourceforge.net
4  * Parts Copyright 1998-1999 Kazuho Okui and Takashi Murai.
5  * All rights reserved. Distributed under the terms of the MIT license.
6  */
7 
8 
9 #include "AppearPrefView.h"
10 #include "MenuUtil.h"
11 #include "PrefHandler.h"
12 #include "PrefWindow.h"
13 #include "PrefView.h"
14 #include "Shell.h"
15 #include "TermConst.h"
16 
17 #include <Alert.h>
18 #include <Box.h>
19 #include <Button.h>
20 #include <FilePanel.h>
21 #include <Path.h>
22 #include <Screen.h>
23 
24 #include <stdio.h>
25 
26 
27 PrefWindow::PrefWindow(BMessenger messenger)
28 	: BWindow(_CenteredRect(BRect(0, 0, 350, 215)), "Terminal Settings",
29 		B_TITLED_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
30 		B_NOT_RESIZABLE|B_NOT_ZOOMABLE),
31 	fPrefTemp(new PrefHandler(PrefHandler::Default())),
32 	fSavePanel(NULL),
33 	fDirty(false),
34 	fPrefDlgMessenger(messenger)
35 {
36 	BRect rect;
37 
38 	BView *top = new BView(Bounds(), "topview", B_FOLLOW_NONE, B_WILL_DRAW);
39 	top->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
40 	AddChild(top);
41 
42 	rect = top->Bounds();
43 	rect.bottom *= .75;
44 	AppearancePrefView *prefView= new AppearancePrefView(rect, "Appearance",
45 		fPrefDlgMessenger);
46 	top->AddChild(prefView);
47 
48 	fSaveAsFileButton = new BButton(BRect(0, 0, 1, 1), "savebutton", "Save to File" B_UTF8_ELLIPSIS,
49 		new BMessage(MSG_SAVEAS_PRESSED), B_FOLLOW_TOP, B_WILL_DRAW);
50 	fSaveAsFileButton->ResizeToPreferred();
51 	fSaveAsFileButton->MoveTo(5, top->Bounds().Height() - 5 -
52 		fSaveAsFileButton->Bounds().Height());
53 	top->AddChild(fSaveAsFileButton);
54 
55 	fSaveButton = new BButton(BRect(0, 0, 1, 1), "okbutton", "OK",
56 		new BMessage(MSG_SAVE_PRESSED), B_FOLLOW_TOP, B_WILL_DRAW);
57 	fSaveButton->ResizeToPreferred();
58 	fSaveButton->MoveTo(top->Bounds().Width() - 5 - fSaveButton->Bounds().Width(),
59 		top->Bounds().Height() - 5 - fSaveButton->Bounds().Height());
60 	fSaveButton->MakeDefault(true);
61 	top->AddChild(fSaveButton);
62 
63 	fRevertButton = new BButton(BRect(0, 0, 1, 1), "revertbutton",
64 		"Cancel", new BMessage(MSG_REVERT_PRESSED), B_FOLLOW_TOP, B_WILL_DRAW);
65 	fRevertButton->ResizeToPreferred();
66 	fRevertButton->MoveTo(fSaveButton->Frame().left - 10 -
67 		fRevertButton->Bounds().Width(), top->Bounds().Height() - 5 -
68 		fRevertButton->Bounds().Height());
69 	top->AddChild(fRevertButton);
70 
71 	AddShortcut((ulong)'Q', (ulong)B_COMMAND_KEY, new BMessage(B_QUIT_REQUESTED));
72 	AddShortcut((ulong)'W', (ulong)B_COMMAND_KEY, new BMessage(B_QUIT_REQUESTED));
73 
74 	Show();
75 }
76 
77 
78 PrefWindow::~PrefWindow()
79 {
80 }
81 
82 
83 void
84 PrefWindow::Quit()
85 {
86 	fPrefDlgMessenger.SendMessage(MSG_PREF_CLOSED);
87 	delete fPrefTemp;
88 	delete fSavePanel;
89 	BWindow::Quit();
90 }
91 
92 
93 bool
94 PrefWindow::QuitRequested()
95 {
96 	if (!fDirty)
97 		return true;
98 
99 	BAlert *alert = new BAlert("", "Save changes to this preference panel?",
100 		"Cancel", "Don't Save", "Save",
101 		B_WIDTH_AS_USUAL, B_OFFSET_SPACING,
102 		B_WARNING_ALERT);
103 	alert->SetShortcut(0, B_ESCAPE);
104 	alert->SetShortcut(1, 'd');
105 	alert->SetShortcut(2, 's');
106 
107 	int32 index = alert->Go();
108 	if (index == 0)
109 		return false;
110 
111 	if (index == 2)
112 		_Save();
113 
114 	return true;
115 }
116 
117 
118 void
119 PrefWindow::_SaveAs()
120 {
121 	if (!fSavePanel)
122 		fSavePanel = new BFilePanel(B_SAVE_PANEL, new BMessenger(this));
123 
124 	fSavePanel->Show();
125 }
126 
127 
128 void
129 PrefWindow::_SaveRequested(BMessage *msg)
130 {
131 	entry_ref dirref;
132 	const char *filename;
133 
134 	msg->FindRef("directory", &dirref);
135 	msg->FindString("name", &filename);
136 
137 	BDirectory dir(&dirref);
138 	BPath path(&dir, filename);
139 
140 	PrefHandler::Default()->SaveAsText(path.Path(), PREFFILE_MIMETYPE, TERM_SIGNATURE);
141 }
142 
143 
144 void
145 PrefWindow::_Save()
146 {
147 	delete fPrefTemp;
148 	fPrefTemp = new PrefHandler(PrefHandler::Default());
149 
150 	BPath path;
151 	if (PrefHandler::GetDefaultPath(path) == B_OK) {
152 		PrefHandler::Default()->SaveAsText(path.Path(), PREFFILE_MIMETYPE);
153 		fDirty = false;
154 	}
155 }
156 
157 
158 void
159 PrefWindow::_Revert()
160 {
161 	PrefHandler::SetDefault(new PrefHandler(fPrefTemp));
162 
163 	fPrefDlgMessenger.SendMessage(MSG_HALF_FONT_CHANGED);
164 	fPrefDlgMessenger.SendMessage(MSG_COLOR_CHANGED);
165 	fPrefDlgMessenger.SendMessage(MSG_INPUT_METHOD_CHANGED);
166 
167 	fDirty = false;
168 }
169 
170 
171 void
172 PrefWindow::MessageReceived(BMessage *msg)
173 {
174 	switch (msg->what) {
175 		case MSG_SAVE_PRESSED:
176 			_Save();
177 			PostMessage(B_QUIT_REQUESTED);
178 			break;
179 
180 		case MSG_SAVEAS_PRESSED:
181 			_SaveAs();
182 			break;
183 
184 		case MSG_REVERT_PRESSED:
185 			_Revert();
186 			PostMessage(B_QUIT_REQUESTED);
187 			break;
188 
189 		case MSG_PREF_MODIFIED:
190 			fDirty = true;
191 			break;
192 
193 		case B_SAVE_REQUESTED:
194 			_SaveRequested(msg);
195 			break;
196 
197 		default:
198 			BWindow::MessageReceived(msg);
199 			break;
200 	}
201 }
202 
203 
204 BRect
205 PrefWindow::_CenteredRect(BRect rect)
206 {
207 	BRect screenRect = BScreen().Frame();
208 
209 	screenRect.InsetBy(10,10);
210 
211 	float x = screenRect.left + (screenRect.Width() - rect.Width()) / 2;
212 	float y = screenRect.top + (screenRect.Height() - rect.Height()) / 3;
213 
214 	rect.OffsetTo(x, y);
215 
216 	return rect;
217 }
218