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