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