vfs: check userland buffers before reading them.
[haiku.git] / src / preferences / media / MidiSettingsView.cpp
blobc1a3209070368a2a93b01e892b0ed7b1f2587e5f
1 /*
2 * Copyright 2014-2017, Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
6 #include "MidiSettingsView.h"
8 #include <MidiSettings.h>
10 #include <Box.h>
11 #include <Catalog.h>
12 #include <Directory.h>
13 #include <Entry.h>
14 #include <FindDirectory.h>
15 #include <GridView.h>
16 #include <LayoutBuilder.h>
17 #include <ListView.h>
18 #include <Locale.h>
19 #include <Node.h>
20 #include <NodeInfo.h>
21 #include <NodeMonitor.h>
22 #include <Path.h>
23 #include <PathFinder.h>
24 #include <ScrollView.h>
25 #include <StringList.h>
26 #include <StringView.h>
28 #include <stdio.h>
31 #undef B_TRANSLATION_CONTEXT
32 #define B_TRANSLATION_CONTEXT "Midi View"
34 const static uint32 kSelectSoundFont = 'SeSf';
35 const static uint32 kDoubleClick = 'DClk';
38 MidiSettingsView::MidiSettingsView()
40 SettingsView()
42 BBox* defaultsBox = new BBox("SoundFonts");
43 defaultsBox->SetLabel(B_TRANSLATE("SoundFonts"));
44 BGridView* defaultsGridView = new BGridView();
46 fListView = new BListView(B_SINGLE_SELECTION_LIST);
47 fListView->SetSelectionMessage(new BMessage(kSelectSoundFont));
48 fListView->SetInvocationMessage(new BMessage(kDoubleClick));
50 BScrollView* scrollView = new BScrollView("ScrollView", fListView,
51 0, false, true);
52 BLayoutBuilder::Grid<>(defaultsGridView)
53 .SetInsets(B_USE_DEFAULT_SPACING, 0, B_USE_DEFAULT_SPACING,
54 B_USE_DEFAULT_SPACING)
55 .Add(scrollView, 0, 0);
57 defaultsBox->AddChild(defaultsGridView);
58 fSoundFontStatus = new BStringView("SoundFontStatus", "");
60 BLayoutBuilder::Group<>(this)
61 .SetInsets(0, 0, 0, 0)
62 .Add(defaultsBox)
63 .AddGroup(B_HORIZONTAL)
64 .AddGlue()
65 .Add(fSoundFontStatus)
66 .AddGlue()
67 .End()
68 .AddGlue();
72 /* virtual */
73 void
74 MidiSettingsView::AttachedToWindow()
76 SettingsView::AttachedToWindow();
78 fListView->SetTarget(this);
79 _LoadSettings();
80 _RetrieveSoundFontList();
81 _SelectActiveSoundFont();
82 _UpdateSoundFontStatus();
83 _WatchFolders();
87 /* virtual */
88 void
89 MidiSettingsView::DetachedFromWindow()
91 SettingsView::DetachedFromWindow();
93 stop_watching(this);
97 /* virtual */
98 void
99 MidiSettingsView::MessageReceived(BMessage* message)
101 switch (message->what) {
102 case B_NODE_MONITOR:
104 int32 selected = fListView->CurrentSelection();
105 BStringItem* olditem = (BStringItem*)fListView->ItemAt(selected);
107 _RetrieveSoundFontList();
109 int32 count = fListView->CountItems();
110 if (count == 1) {
111 fListView->Select(0);
112 _SaveSettings();
113 } else if (olditem != NULL) {
114 for (int32 i = 0; i < fListView->CountItems(); i++) {
115 BStringItem* item = (BStringItem*)fListView->ItemAt(i);
116 if (strcmp(item->Text(), olditem->Text()) == 0) {
117 fListView->Select(i);
118 break;
122 _UpdateSoundFontStatus();
123 break;
125 case kSelectSoundFont:
127 int selection = fListView->CurrentSelection();
128 if (selection < 0)
129 _SelectActiveSoundFont();
130 else
131 _SaveSettings();
133 _UpdateSoundFontStatus();
134 break;
136 case kDoubleClick:
138 int selection = fListView->CurrentSelection();
139 if (selection < 0)
140 break;
142 BStringItem* item = (BStringItem*)fListView->ItemAt(selection);
144 BEntry entry(item->Text());
145 BEntry parent;
146 entry.GetParent(&parent);
147 entry_ref folderRef;
148 parent.GetRef(&folderRef);
149 BMessenger msgr("application/x-vnd.Be-TRAK");
150 BMessage refMsg(B_REFS_RECEIVED);
151 refMsg.AddRef("refs",&folderRef);
152 msgr.SendMessage(&refMsg);
153 break;
156 default:
157 SettingsView::MessageReceived(message);
158 break;
163 void
164 MidiSettingsView::_RetrieveSoundFontList()
166 // TODO: Duplicated code between here
167 // and BSoftSynth::SetDefaultInstrumentsFile
168 BStringList paths;
169 status_t status = BPathFinder::FindPaths(B_FIND_PATH_DATA_DIRECTORY,
170 "synth", paths);
171 if (status != B_OK)
172 return;
174 fListView->MakeEmpty();
176 for (int32 i = 0; i < paths.CountStrings(); i++) {
177 BDirectory directory(paths.StringAt(i).String());
178 BEntry entry;
179 if (directory.InitCheck() != B_OK)
180 continue;
181 while (directory.GetNextEntry(&entry) == B_OK) {
182 BNode node(&entry);
183 BNodeInfo nodeInfo(&node);
184 char mimeType[B_MIME_TYPE_LENGTH];
185 // TODO: For some reason the mimetype check fails.
186 // maybe because the file hasn't yet been sniffed and recognized?
187 if (nodeInfo.GetType(mimeType) == B_OK
188 /*&& !strcmp(mimeType, "audio/x-soundfont")*/) {
189 BPath fullPath = paths.StringAt(i).String();
190 fullPath.Append(entry.Name());
191 fListView->AddItem(new BStringItem(fullPath.Path()));
198 void
199 MidiSettingsView::_LoadSettings()
201 struct BPrivate::midi_settings settings;
202 if (BPrivate::read_midi_settings(&settings) == B_OK)
203 fActiveSoundFont.SetTo(settings.soundfont_file);
207 void
208 MidiSettingsView::_SaveSettings()
210 fActiveSoundFont = _SelectedSoundFont();
211 if (fActiveSoundFont.Length() > 0) {
212 struct BPrivate::midi_settings settings;
213 strlcpy(settings.soundfont_file, fActiveSoundFont.String(),
214 sizeof(settings.soundfont_file));
215 BPrivate::write_midi_settings(settings);
220 void
221 MidiSettingsView::_SelectActiveSoundFont()
223 int32 count = fListView->CountItems();
224 if (count == 1) {
225 fListView->Select(0);
226 _SaveSettings();
227 return;
229 for (int32 i = 0; i < fListView->CountItems(); i++) {
230 BStringItem* item = (BStringItem*)fListView->ItemAt(i);
231 if (strcmp(item->Text(), fActiveSoundFont.String()) == 0) {
232 fListView->Select(i);
233 break;
239 BString
240 MidiSettingsView::_SelectedSoundFont() const
242 BString string;
243 int32 selection = fListView->CurrentSelection();
244 if (selection >= 0) {
245 BStringItem* item = (BStringItem*)fListView->ItemAt(selection);
246 if (item != NULL)
247 string = item->Text();
250 return string;
254 void
255 MidiSettingsView::_UpdateSoundFontStatus()
257 if (fListView->IsEmpty()) {
258 fSoundFontStatus->SetText(
259 B_TRANSLATE("There are no SoundFont installed."));
260 return;
262 int32 selection = fListView->CurrentSelection();
263 if (selection < 0) {
264 fSoundFontStatus->SetText(
265 B_TRANSLATE("Please select a SoundFont."));
266 return;
268 fSoundFontStatus->SetText("");
272 void
273 MidiSettingsView::_WatchFolders()
275 BStringList paths;
276 BPathFinder().FindPaths(B_FIND_PATH_DATA_DIRECTORY, "synth", paths);
277 for (int32 i = 0; i < paths.CountStrings(); i++) {
278 BEntry entry(paths.StringAt(i));
279 node_ref nref;
280 entry.GetNodeRef(&nref);
282 watch_node(&nref, B_WATCH_ALL, this);