xref: /haiku/src/preferences/datatranslations/DataTranslationsWindow.cpp (revision 93aeb8c3bc3f13cb1f282e3e749258a23790d947)
1 /*
2  * DataTranslationsWindow.cpp
3  *
4  */
5 
6 #include <Application.h>
7 #include <Message.h>
8 #include <Screen.h>
9 #include <TranslationDefs.h>
10 #include "DataTranslationsMessages.h"
11 #include "DataTranslationsWindow.h"
12 #include "DataTranslations.h"
13 
14 #define DTW_RIGHT	400
15 #define DTW_BOTTOM	300
16 
17 DataTranslationsWindow::DataTranslationsWindow()
18 	: BWindow(BRect(0, 0, DTW_RIGHT, DTW_BOTTOM),
19 		"DataTranslations", B_TITLED_WINDOW, B_NOT_ZOOMABLE|B_NOT_RESIZABLE)
20 {
21 	MoveTo(dynamic_cast<DataTranslationsApplication *>(be_app)->WindowCorner());
22 
23 	// Make sure that the window isn't positioned off screen
24 	BScreen screen;
25 	BRect scrf = screen.Frame(), winf = Frame();
26 	float x = winf.left, y = winf.top;
27 	scrf.top += 24;
28 	scrf.left += 5;
29 	scrf.right -= 5;
30 	if (winf.left < scrf.left)
31 		x = scrf.left;
32 	if (winf.right > scrf.right)
33 		x = scrf.right - winf.Width() - 5;
34 	if (winf.top < scrf.top)
35 		y = scrf.top;
36 	if (winf.bottom > scrf.bottom)
37 		y = scrf.bottom - winf.Height() - 15;
38 
39 	if (x != winf.left || y != winf.top)
40 		MoveTo(x, y);
41 
42 	SetupViews();
43 	Show();
44 }
45 
46 DataTranslationsWindow::~DataTranslationsWindow()
47 {
48 }
49 
50 // Reads the installed translators and adds them to our BListView
51 status_t
52 DataTranslationsWindow::PopulateListView()
53 {
54 	BTranslatorRoster *roster = BTranslatorRoster::Default();
55 
56 	// Get all Translators on the system. Gives us the number of translators
57 	// installed in num_translators and a reference to the first one
58 	int32 num_translators;
59 	translator_id *translators;
60 	roster->GetAllTranslators(&translators, &num_translators);
61 
62 	for (int32 i = 0; i < num_translators; i++) {
63 	    // Getting the first three Infos: Name, Info & Version
64 	    int32 tversion;
65 	    const char *tname, *tinfo;
66 		roster->GetTranslatorInfo(translators[i], &tname, &tinfo, &tversion);
67 		fTranListView->AddItem(new BStringItem(tname));
68 	}
69 
70 	delete[] translators;
71 	translators = NULL;
72 
73 	return B_OK;
74 }
75 
76 status_t
77 DataTranslationsWindow::GetTranInfo(int32 id, const char *&tranName,
78 	const char *&tranInfo, int32 &tranVersion, BPath &tranPath)
79 {
80 	// Returns information about the translator with the given id
81 
82 	if (id < 0)
83 		return B_BAD_VALUE;
84 
85 	int32 num_translators = 0;
86 	translator_id tid = 0, *translators = NULL;
87 	BTranslatorRoster *roster = BTranslatorRoster::Default();
88 	roster->GetAllTranslators(&translators, &num_translators);
89 	tid = ((id < num_translators) ? translators[id] : 0);
90 	delete[] translators;
91 	translators = NULL;
92 
93 	if (id >= num_translators)
94 		return B_BAD_VALUE;
95 
96 	// Getting the first three Infos: Name, Info & Version
97 	roster->GetTranslatorInfo(tid, &tranName, &tranInfo, &tranVersion);
98 
99 	// Get the translator's path
100 	entry_ref tranRef;
101 	roster->GetRefFor(tid, &tranRef);
102 	BEntry tmpEntry(&tranRef);
103 	tranPath.SetTo(&tmpEntry);
104 
105 	return B_OK;
106 }
107 
108 status_t
109 DataTranslationsWindow::ShowConfigView(int32 id)
110 {
111 	// Shows the config panel for the translator with the given id
112 
113 	if (id < 0)
114 		return B_BAD_VALUE;
115 
116 	int32 num_translators = 0;
117 	translator_id tid = 0, *translators = NULL;
118 	BTranslatorRoster *roster = BTranslatorRoster::Default();
119 	roster->GetAllTranslators(&translators, &num_translators);
120 	tid = ((id < num_translators) ? translators[id] : 0);
121 	delete[] translators;
122 	translators = NULL;
123 
124 	if (id >= num_translators)
125 		return B_BAD_VALUE;
126 
127 	// fConfigView is NULL the first time this function
128 	// is called, prevent a segment fault
129 	if (fConfigView)
130 		fRightBox->RemoveChild(fConfigView);
131 	BMessage emptyMsg;
132 	BRect rect(0, 0, 200, 233);
133 	status_t ret = roster->MakeConfigurationView(tid, &emptyMsg, &fConfigView, &rect);
134 	if (ret != B_OK) {
135 		fRightBox->RemoveChild(fConfigView);
136 		return ret;
137 	}
138 
139 	BRect configRect(fRightBox->Bounds());
140 	configRect.InsetBy(3, 3);
141 	configRect.bottom -= 45;
142 	float width = 0, height = 0;
143 	fConfigView->GetPreferredSize(&width, &height);
144 	float widen = max_c(0, width - configRect.Width());
145 	float heighten = max_c(0, height - configRect.Height());
146 	if (widen > 0 || heighten > 0) {
147 		ResizeBy(widen, heighten);
148 		configRect.right += widen;
149 		configRect.bottom += heighten;
150 	}
151 	fConfigView->MoveTo(configRect.left, configRect.top);
152 	fConfigView->ResizeTo(configRect.Width(), configRect.Height());
153 	fConfigView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
154 		// force config views to all have the same color
155 	fRightBox->AddChild(fConfigView);
156 
157 	UpdateIfNeeded();
158 
159 	return B_OK;
160 }
161 
162 void
163 DataTranslationsWindow::SetupViews()
164 {
165 	fConfigView = NULL;
166 	// This is NULL until a translator is
167 	// selected from the listview
168 
169 	// Window box
170 	BBox *mainBox = new BBox(BRect(0, 0, DTW_RIGHT, DTW_BOTTOM),
171 		"All_Window", B_FOLLOW_ALL_SIDES,
172 		B_WILL_DRAW | B_FRAME_EVENTS, B_PLAIN_BORDER);
173 	AddChild(mainBox);
174 
175 	// Box around the config and info panels
176 	fRightBox = new BBox(BRect(150, 10, 390, 290), "Right_Side",
177 		B_FOLLOW_ALL_SIDES);
178 	mainBox->AddChild(fRightBox);
179 
180 	// Add the translator icon view
181 	BRect rightRect(fRightBox->Bounds()), iconRect(0, 0, 31, 31);
182 	rightRect.InsetBy(8, 8);
183 	iconRect.OffsetTo(rightRect.left, rightRect.bottom - iconRect.Height());
184 	fIconView = new IconView(iconRect, "Icon",
185 		B_FOLLOW_LEFT | B_FOLLOW_BOTTOM, B_WILL_DRAW | B_FRAME_EVENTS);
186 	fRightBox->AddChild(fIconView);
187 
188 	// Add the translator info button
189 	BRect infoRect(0, 0, 80, 20);
190 	infoRect.OffsetTo(rightRect.right - infoRect.Width(),
191 		rightRect.bottom - 10 - infoRect.Height());
192 	BButton *button = new BButton(infoRect, "STD", "Info...",
193 		new BMessage(BUTTON_MSG), B_FOLLOW_BOTTOM | B_FOLLOW_RIGHT,
194 		B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE);
195 	fRightBox->AddChild(button);
196 
197 	// Add the translator name view
198 	BRect tranNameRect(iconRect.right + 5, iconRect.top,
199 		infoRect.left - 5, iconRect.bottom);
200 	fTranNameView = new BStringView(tranNameRect, "TranName", "None",
201     		B_FOLLOW_LEFT | B_FOLLOW_V_CENTER);
202 	fRightBox->AddChild(fTranNameView);
203 
204 	// Add the translators list view
205 	fTranListView = new DataTranslationsView(BRect(10, 10, 120, 288),
206 		"TransList", B_SINGLE_SELECTION_LIST);
207 	fTranListView->SetSelectionMessage(new BMessage(SEL_CHANGE));
208 
209 	BScrollView *scrollView = new BScrollView("scroll_trans", fTranListView,
210     		B_FOLLOW_LEFT | B_FOLLOW_TOP_BOTTOM, B_WILL_DRAW | B_FRAME_EVENTS,
211     		false, true, B_FANCY_BORDER);
212 	mainBox->AddChild(scrollView);
213 
214 	// Populate the translators list view
215 	PopulateListView();
216 
217 	// Set the focus
218 	fTranListView->MakeFocus();
219 
220 	// Select the first Translator in list
221 	fTranListView->Select(0, false);
222 }
223 
224 bool
225 DataTranslationsWindow::QuitRequested()
226 {
227 	BPoint pt(Frame().left, Frame().top);
228 	dynamic_cast<DataTranslationsApplication *>(be_app)->SetWindowCorner(pt);
229 	be_app->PostMessage(B_QUIT_REQUESTED);
230 
231 	return true;
232 }
233 
234 void
235 DataTranslationsWindow::MessageReceived(BMessage *message)
236 {
237 	BPath tranPath;
238 	BString strInfoMsg;
239 	const char *tranName = NULL, *tranInfo = NULL;
240 	int32 selected = -1, tranVersion = 0;
241 
242 	switch (message->what) {
243 
244 		case BUTTON_MSG:
245 			selected = fTranListView->CurrentSelection(0);
246 			if (selected < 0) {
247 				// If no translator is selected, show a message explaining
248 				// what the config panel is for
249 				(new BAlert("Panel Info",
250 					"Translation Settings\n\n"
251 					"Use this control panel to set values that various\n"
252 					"translators use when no other settings are specified\n"
253 					"in the application.",
254 					"OK"))->Go();
255 				break;
256 			}
257 
258 			GetTranInfo(selected, tranName, tranInfo, tranVersion, tranPath);
259 			strInfoMsg << "Name: " << tranName << "\nVersion: ";
260 			if (tranVersion < 0x100)
261 				// If the version number doesn't follow the standard format,
262 				// just print it as is
263 				strInfoMsg << tranVersion;
264 			else {
265 				// Convert the version number into a readable format
266 				strInfoMsg <<
267 					static_cast<int>(B_TRANSLATION_MAJOR_VERSION(tranVersion)) << '.' <<
268 					static_cast<int>(B_TRANSLATION_MINOR_VERSION(tranVersion)) << '.' <<
269 					static_cast<int>(B_TRANSLATION_REVISION_VERSION(tranVersion));
270 			}
271 			strInfoMsg << "\nInfo: " << tranInfo <<
272 				"\nPath: " << tranPath.Path() << "\n";
273 
274 			(new BAlert("Panel Info", strInfoMsg.String(), "OK"))->Go();
275 			break;
276 
277 		case SEL_CHANGE:
278 			// Update the icon and translator info panel
279 			// to match the new selection
280 			selected = fTranListView->CurrentSelection(0);
281 			if (selected < 0) {
282 				// If none selected, clear the old one
283 				fIconView->DrawIcon(false);
284 				fTranNameView->SetText("");
285 				fRightBox->RemoveChild(fConfigView);
286 				break;
287 			}
288 
289 			ShowConfigView(selected);
290 			GetTranInfo(selected, tranName, tranInfo, tranVersion, tranPath);
291 			fTranNameView->SetText(tranPath.Leaf());
292 			fIconView->SetIcon(tranPath);
293 			break;
294 
295 		default:
296 			BWindow::MessageReceived(message);
297 			break;
298 	}
299 }
300 
301