xref: /haiku/src/preferences/media/MidiSettingsView.cpp (revision f262f1b66e32205eff6725ae88a0541bc78fc4f2)
1 /*
2  * Copyright 2014, Haiku, Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 #include "MidiSettingsView.h"
7 
8 #include <Box.h>
9 #include <Catalog.h>
10 #include <Directory.h>
11 #include <Entry.h>
12 #include <FindDirectory.h>
13 #include <GridView.h>
14 #include <LayoutBuilder.h>
15 #include <ListView.h>
16 #include <Locale.h>
17 #include <Node.h>
18 #include <NodeInfo.h>
19 #include <Path.h>
20 #include <PathFinder.h>
21 #include <ScrollView.h>
22 #include <StringList.h>
23 
24 #include <stdio.h>
25 
26 
27 #undef B_TRANSLATION_CONTEXT
28 #define B_TRANSLATION_CONTEXT "Midi View"
29 
30 #define SETTINGS_FILE "midi"
31 
32 const static uint32 kSelectSoundFont = 'SeSf';
33 
34 
35 MidiSettingsView::MidiSettingsView()
36 	:
37 	SettingsView()
38 {
39 	BBox* defaultsBox = new BBox("SoundFont");
40 	defaultsBox->SetLabel(B_TRANSLATE("SoundFont"));
41 	BGridView* defaultsGridView = new BGridView();
42 
43 	fListView = new BListView(B_SINGLE_SELECTION_LIST);
44 	fListView->SetSelectionMessage(new BMessage(kSelectSoundFont));
45 
46 	BScrollView *scrollView = new BScrollView("ScrollView", fListView,
47 			0, false, true);
48 	BLayoutBuilder::Grid<>(defaultsGridView)
49 		.SetInsets(B_USE_DEFAULT_SPACING, 0, B_USE_DEFAULT_SPACING,
50 				B_USE_DEFAULT_SPACING)
51 		.Add(scrollView, 0, 0);
52 
53 	defaultsBox->AddChild(defaultsGridView);
54 
55 	BLayoutBuilder::Group<>(this)
56 		.SetInsets(0, 0, 0, 0)
57 		.Add(defaultsBox)
58 		.AddGlue();
59 }
60 
61 
62 /* virtual */
63 void
64 MidiSettingsView::AttachedToWindow()
65 {
66 	SettingsView::AttachedToWindow();
67 
68 	fListView->SetTarget(this);
69 	_RetrieveSoftSynthList();
70 
71 	_LoadSettings();
72 }
73 
74 
75 /* virtual */
76 void
77 MidiSettingsView::MessageReceived(BMessage* message)
78 {
79 	switch (message->what) {
80 		case kSelectSoundFont:
81 			_SaveSettings();
82 			break;
83 
84 		default:
85 			SettingsView::MessageReceived(message);
86 			break;
87 	}
88 }
89 
90 
91 void
92 MidiSettingsView::_RetrieveSoftSynthList()
93 {
94 	BStringList paths;
95 	status_t status = BPathFinder::FindPaths(B_FIND_PATH_DATA_DIRECTORY,
96 			"synth", paths);
97 	if (status != B_OK)
98 		return;
99 
100 	fListView->MakeEmpty();
101 
102 	for (int32 i = 0; i < paths.CountStrings(); i++) {
103 		BDirectory directory(paths.StringAt(i).String());
104 		BEntry entry;
105 		if (directory.InitCheck() != B_OK)
106 			continue;
107 		while (directory.GetNextEntry(&entry) == B_OK) {
108 			// TODO: Get rid of this as soon as we update
109 			// the SoundFont package not to create the link
110 			// anymore
111 			if (!strcmp(entry.Name(), "big_synth.sy"))
112 				continue;
113 			BNode node(&entry);
114 			BNodeInfo nodeInfo(&node);
115 			char mimeType[B_MIME_TYPE_LENGTH];
116 			// TODO: For some reason this doesn't work
117 			if (nodeInfo.GetType(mimeType) == B_OK
118 					/*&& !strcmp(mimeType, "audio/x-soundfont")*/) {
119 				BPath fullPath = paths.StringAt(i).String();
120 				fullPath.Append(entry.Name());
121 				fListView->AddItem(new BStringItem(fullPath.Path()));
122 			}
123 		}
124 	}
125 }
126 
127 
128 void
129 MidiSettingsView::_LoadSettings()
130 {
131 	// TODO: Duplicated code between here
132 	// and BSoftSynth::LoadDefaultInstruments
133 
134 	char buffer[512];
135 	BPath path;
136 	if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) == B_OK) {
137 		path.Append(SETTINGS_FILE);
138 		BFile file(path.Path(), B_READ_ONLY);
139 		if (file.InitCheck() == B_OK)
140 			file.Read(buffer, sizeof(buffer));
141 	}
142 
143 	char soundFont[512];
144 	sscanf(buffer, "# Midi Settings\n soundfont = %s\n",
145 		soundFont);
146 
147 	for (int32 i = 0; i < fListView->CountItems(); i++) {
148 		BStringItem* item = (BStringItem*)fListView->ItemAt(i);
149 		if (!strcmp(item->Text(), soundFont)) {
150 			fListView->Select(i);
151 			break;
152 		}
153 	}
154 }
155 
156 
157 void
158 MidiSettingsView::_SaveSettings()
159 {
160 	int32 selection = fListView->CurrentSelection();
161 	if (selection < 0)
162 		return;
163 	BStringItem* item = (BStringItem*)fListView->ItemAt(selection);
164 	if (item == NULL)
165 		return;
166 
167 	char buffer[512];
168 	snprintf(buffer, 512, "# Midi Settings\n soundfont = %s\n",
169 			item->Text());
170 
171 	BPath path;
172 	if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) == B_OK) {
173 		path.Append(SETTINGS_FILE);
174 		BFile file(path.Path(), B_READ_WRITE | B_CREATE_FILE | B_ERASE_FILE);
175 		if (file.InitCheck() == B_OK)
176 			file.Write(buffer, strlen(buffer));
177 	}
178 }
179 
180