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