fat: Greatly simplify and clean up dosfs_get_file_map().
[haiku.git] / src / preferences / datatranslations / DataTranslationsWindow.cpp
blob2d71c4001237a76f94d226a468bba27681597743
1 /*
2 * Copyright 2002-2014, Haiku, Inc.
3 * Distributed under the terms of the MIT license.
5 * Authors:
6 * Oliver Siebenmarck
7 * Andrew McCall, mccall@digitalparadise.co.uk
8 * Michael Wilber
9 * Maxime Simon
13 #include "DataTranslationsWindow.h"
15 #include <algorithm>
16 #include <stdio.h>
18 #include <Alert.h>
19 #include <Alignment.h>
20 #include <Application.h>
21 #include <Bitmap.h>
22 #include <Box.h>
23 #include <Catalog.h>
24 #include <ControlLook.h>
25 #include <Entry.h>
26 #include <GroupView.h>
27 #include <IconView.h>
28 #include <LayoutBuilder.h>
29 #include <ListView.h>
30 #include <Path.h>
31 #include <Screen.h>
32 #include <ScrollView.h>
33 #include <String.h>
34 #include <StringView.h>
35 #include <TextView.h>
36 #include <TranslationDefs.h>
37 #include <TranslatorRoster.h>
39 #include "DataTranslations.h"
40 #include "DataTranslationsSettings.h"
41 #include "TranslatorListView.h"
44 #undef B_TRANSLATION_CONTEXT
45 #define B_TRANSLATION_CONTEXT "DataTranslations"
48 const uint32 kMsgTranslatorInfo = 'trin';
49 const uint32 kMsgSelectedTranslator = 'trsl';
52 DataTranslationsWindow::DataTranslationsWindow()
54 BWindow(BRect(0, 0, 550, 350), B_TRANSLATE_SYSTEM_NAME("DataTranslations"),
55 B_TITLED_WINDOW, B_ASYNCHRONOUS_CONTROLS | B_NOT_ZOOMABLE
56 | B_NOT_RESIZABLE | B_AUTO_UPDATE_SIZE_LIMITS)
58 MoveTo(DataTranslationsSettings::Instance()->WindowCorner());
60 _SetupViews();
62 // Make sure that the window isn't positioned off screen
63 BScreen screen;
64 BRect screenFrame = screen.Frame();
65 if (!screenFrame.Contains(Frame()))
66 CenterOnScreen();
68 BTranslatorRoster* roster = BTranslatorRoster::Default();
69 roster->StartWatching(this);
71 Show();
75 DataTranslationsWindow::~DataTranslationsWindow()
77 BTranslatorRoster* roster = BTranslatorRoster::Default();
78 roster->StopWatching(this);
82 // Reads the installed translators and adds them to our BListView
83 status_t
84 DataTranslationsWindow::_PopulateListView()
86 BTranslatorRoster* roster = BTranslatorRoster::Default();
88 // Get all Translators on the system. Gives us the number of translators
89 // installed in num_translators and a reference to the first one
90 int32 numTranslators;
91 translator_id* translators = NULL;
92 roster->GetAllTranslators(&translators, &numTranslators);
94 float maxWidth = 0;
96 for (int32 i = 0; i < numTranslators; i++) {
97 // Getting the first three Infos: Name, Info & Version
98 int32 version;
99 const char* name;
100 const char* info;
101 roster->GetTranslatorInfo(translators[i], &name, &info, &version);
102 fTranslatorListView->AddItem(new TranslatorItem(translators[i], name));
103 maxWidth = std::max(maxWidth, fTranslatorListView->StringWidth(name));
106 fTranslatorListView->SortItems();
108 fTranslatorListView->SetExplicitSize(BSize(maxWidth + 20, B_SIZE_UNSET));
110 delete[] translators;
111 return B_OK;
115 status_t
116 DataTranslationsWindow::_GetTranslatorInfo(int32 id, const char*& name,
117 const char*& info, int32& version, BPath& path)
119 // Returns information about the translator with the given id
121 if (id < 0)
122 return B_BAD_VALUE;
124 BTranslatorRoster* roster = BTranslatorRoster::Default();
125 if (roster->GetTranslatorInfo(id, &name, &info, &version) != B_OK)
126 return B_ERROR;
128 // Get the translator's path
129 entry_ref ref;
130 if (roster->GetRefFor(id, &ref) == B_OK) {
131 BEntry entry(&ref);
132 path.SetTo(&entry);
133 } else
134 path.Unset();
136 return B_OK;
140 status_t
141 DataTranslationsWindow::_ShowConfigView(int32 id)
143 // Shows the config panel for the translator with the given id
145 if (id < 0)
146 return B_BAD_VALUE;
148 BTranslatorRoster* roster = BTranslatorRoster::Default();
150 if (fConfigView) {
151 fRightBox->RemoveChild(fConfigView);
152 delete fConfigView;
153 fConfigView = NULL;
156 BMessage emptyMsg;
157 BRect rect(0, 0, 200, 233);
158 status_t ret = roster->MakeConfigurationView(id, &emptyMsg,
159 &fConfigView, &rect);
161 if (ret != B_OK)
162 return ret;
164 fConfigView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
165 // force config views to all have the same color
166 fRightBox->AddChild(fConfigView);
168 return B_OK;
172 void
173 DataTranslationsWindow::_ShowInfoView()
175 if (fConfigView) {
176 fRightBox->RemoveChild(fConfigView);
177 delete fConfigView;
178 fConfigView = NULL;
181 BTextView* view = new BTextView("info text");
182 view->MakeEditable(false);
183 view->MakeSelectable(false);
184 view->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
185 view->SetText(B_TRANSLATE(
186 "Use this control panel to set default values for translators, "
187 "to be used when no other settings are specified by an application."));
189 BGroupView* group = new BGroupView(B_VERTICAL);
190 group->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
191 group->AddChild(view);
192 float spacing = be_control_look->DefaultItemSpacing();
193 group->GroupLayout()->SetInsets(spacing, spacing, spacing, spacing);
194 fRightBox->AddChild(group);
195 fConfigView = group;
199 void
200 DataTranslationsWindow::_SetupViews()
202 fConfigView = NULL;
203 // This is NULL until a translator is
204 // selected from the listview
206 // Add the translators list view
207 fTranslatorListView = new TranslatorListView("TransList");
208 fTranslatorListView->SetSelectionMessage(
209 new BMessage(kMsgSelectedTranslator));
211 BScrollView* scrollView = new BScrollView("scroll_trans",
212 fTranslatorListView, B_WILL_DRAW | B_FRAME_EVENTS, false,
213 true, B_FANCY_BORDER);
215 // Box around the config and info panels
216 fRightBox = new BBox("Right_Side");
217 fRightBox->SetExplicitAlignment(BAlignment(B_ALIGN_USE_FULL_WIDTH,
218 B_ALIGN_USE_FULL_HEIGHT));
220 // Add the translator icon view
221 fIconView = new IconView();
223 // Add the translator info button
224 fButton = new BButton("info", B_TRANSLATE("Info"),
225 new BMessage(kMsgTranslatorInfo),
226 B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE);
227 fButton->SetEnabled(false);
229 // Populate the translators list view
230 _PopulateListView();
232 // Build the layout
233 BLayoutBuilder::Group<>(this, B_HORIZONTAL)
234 .SetInsets(B_USE_DEFAULT_SPACING)
235 .Add(scrollView, 3)
236 .AddGrid(B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING, 6)
237 .SetInsets(0, 0, 0, 0)
238 .Add(fRightBox, 0, 0, 3, 1)
239 .Add(fIconView, 0, 1)
240 .Add(fButton, 2, 1);
242 fTranslatorListView->MakeFocus();
243 _ShowInfoView();
247 bool
248 DataTranslationsWindow::QuitRequested()
250 BPoint pt(Frame().LeftTop());
251 DataTranslationsSettings::Instance()->SetWindowCorner(pt);
252 be_app->PostMessage(B_QUIT_REQUESTED);
253 return true;
257 void
258 DataTranslationsWindow::_ShowInfoAlert(int32 id)
260 const char* name = NULL;
261 const char* info = NULL;
262 BPath path;
263 int32 version = 0;
264 _GetTranslatorInfo(id, name, info, version, path);
266 BString message;
267 // Convert the version number into a readable format
268 snprintf(message.LockBuffer(2048), 2048,
269 B_TRANSLATE("Name: %s \nVersion: %ld.%ld.%ld\n\n"
270 "Info:\n%s\n\nPath:\n%s\n"),
271 name, B_TRANSLATION_MAJOR_VERSION(version),
272 B_TRANSLATION_MINOR_VERSION(version),
273 B_TRANSLATION_REVISION_VERSION(version), info, path.Path());
274 message.UnlockBuffer();
276 BAlert* alert = new BAlert(B_TRANSLATE("Info"), message.String(),
277 B_TRANSLATE("OK"));
278 BTextView* view = alert->TextView();
279 BFont font;
281 view->SetStylable(true);
283 view->GetFont(&font);
284 font.SetFace(B_BOLD_FACE);
286 const char* labels[] = { B_TRANSLATE("Name:"), B_TRANSLATE("Version:"),
287 B_TRANSLATE("Info:"), B_TRANSLATE("Path:"), NULL };
288 for (int32 i = 0; labels[i]; i++) {
289 int32 index = message.FindFirst(labels[i]);
290 view->SetFontAndColor(index, index + strlen(labels[i]), &font);
293 alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
294 alert->Go();
298 void
299 DataTranslationsWindow::MessageReceived(BMessage* message)
301 switch (message->what) {
302 case kMsgTranslatorInfo:
304 int32 selected = fTranslatorListView->CurrentSelection(0);
305 if (selected < 0)
306 break;
308 TranslatorItem* item = fTranslatorListView->TranslatorAt(selected);
309 if (item != NULL)
310 _ShowInfoAlert(item->ID());
311 break;
314 case kMsgSelectedTranslator:
316 // Update the icon and translator info panel
317 // to match the new selection
319 int32 selected = fTranslatorListView->CurrentSelection(0);
320 if (selected < 0) {
321 // If none selected, clear the old one
322 fIconView->DrawIcon(false);
323 fButton->SetEnabled(false);
324 fRightBox->RemoveChild(fConfigView);
325 _ShowInfoView();
326 break;
329 TranslatorItem* item = fTranslatorListView->TranslatorAt(selected);
330 if (item == NULL)
331 break;
333 _ShowConfigView(item->ID());
335 const char* name = NULL;
336 const char* info = NULL;
337 int32 version = 0;
338 BPath path;
339 _GetTranslatorInfo(item->ID(), name, info, version, path);
340 fIconView->SetIcon(path);
341 fButton->SetEnabled(true);
342 break;
345 case B_TRANSLATOR_ADDED:
347 int32 index = 0, id;
348 while (message->FindInt32("translator_id", index++, &id) == B_OK) {
349 const char* name;
350 const char* info;
351 int32 version;
352 BPath path;
353 if (_GetTranslatorInfo(id, name, info, version, path) == B_OK)
354 fTranslatorListView->AddItem(new TranslatorItem(id, name));
357 fTranslatorListView->SortItems();
358 break;
361 case B_TRANSLATOR_REMOVED:
363 int32 index = 0, id;
364 while (message->FindInt32("translator_id", index++, &id) == B_OK) {
365 for (int32 i = 0; i < fTranslatorListView->CountItems(); i++) {
366 TranslatorItem* item = fTranslatorListView->TranslatorAt(i);
368 if (item == NULL)
369 continue;
371 if (item->ID() == (translator_id)id) {
372 fTranslatorListView->RemoveItem(i);
373 delete item;
374 break;
378 break;
381 default:
382 BWindow::MessageReceived(message);
383 break;