X-Git-Url: https://main.carlh.net/gitweb/?p=ardour.git;a=blobdiff_plain;f=libs%2Fardour%2Fmidi_patch_manager.cc;h=8a6d8dfd100a5a88be14a8bfc47b6cb076b5e250;hp=4587b1aad9d483243f963ffa14b467eb04db553c;hb=c8c6bca6587450ff64303dbc994a4cd28d6ce7aa;hpb=8c9749e42faf7808034ed8b7afce4a2fe6dc6f33 diff --git a/libs/ardour/midi_patch_manager.cc b/libs/ardour/midi_patch_manager.cc index 4587b1aad9..8a6d8dfd10 100644 --- a/libs/ardour/midi_patch_manager.cc +++ b/libs/ardour/midi_patch_manager.cc @@ -25,13 +25,11 @@ #include "pbd/file_utils.h" #include "pbd/error.h" -#include "ardour/session.h" -#include "ardour/session_directory.h" #include "ardour/midi_patch_manager.h" #include "ardour/search_paths.h" -#include "i18n.h" +#include "pbd/i18n.h" using namespace std; using namespace ARDOUR; @@ -43,108 +41,153 @@ MidiPatchManager* MidiPatchManager::_manager = 0; MidiPatchManager::MidiPatchManager () { - refresh (); + add_search_path(midi_patch_search_path ()); } void -MidiPatchManager::set_session (Session* s) +MidiPatchManager::add_search_path (const Searchpath& search_path) { - SessionHandlePtr::set_session (s); - add_session_patches (); + for (Searchpath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) { + + if (_search_path.contains(*i)) { + // already processed files from this path + continue; + } + + if (!Glib::file_test (*i, Glib::FILE_TEST_EXISTS)) { + continue; + } + + if (!Glib::file_test (*i, Glib::FILE_TEST_IS_DIR)) { + continue; + } + + add_midnam_files_from_directory (*i); + + _search_path.add_directory (*i); + } } void -MidiPatchManager::add_session_patches () +MidiPatchManager::add_midnam_files_from_directory(const std::string& directory_path) { - if (!_session) { - return; - } - - std::string path_to_patches = _session->session_directory().midi_patch_path(); + vector result; + find_files_matching_pattern (result, directory_path, "*.midnam"); - if (!Glib::file_test (path_to_patches, Glib::FILE_TEST_EXISTS)) { - return; - } + info << string_compose( + P_("Loading %1 MIDI patch from %2", "Loading %1 MIDI patches from %2", result.size()), + result.size(), directory_path) + << endmsg; - assert (Glib::file_test (path_to_patches, Glib::FILE_TEST_IS_DIR)); + for (vector::const_iterator i = result.begin(); i != result.end(); ++i) { + add_midi_name_document (*i); + } +} - Glib::PatternSpec pattern(string("*.midnam")); - vector result; +void +MidiPatchManager::remove_search_path (const Searchpath& search_path) +{ + for (Searchpath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) { - find_matching_files_in_directory (path_to_patches, pattern, result); - - info << "Loading " << result.size() << " MIDI patches from " << path_to_patches << endmsg; - - for (vector::iterator i = result.begin(); i != result.end(); ++i) { - boost::shared_ptr document(new MIDINameDocument(*i)); - for (MIDINameDocument::MasterDeviceNamesList::const_iterator device = - document->master_device_names_by_model().begin(); - device != document->master_device_names_by_model().end(); - ++device) { - //cerr << "got model " << device->first << endl; - // have access to the documents by model name - _documents[device->first] = document; - // build a list of all master devices from all documents - _master_devices_by_model[device->first] = device->second; - _all_models.insert(device->first); - - // make sure there are no double model names - // TODO: handle this gracefully. - assert(_documents.count(device->first) == 1); - assert(_master_devices_by_model.count(device->first) == 1); + if (!_search_path.contains(*i)) { + continue; } + + remove_midnam_files_from_directory(*i); + + _search_path.remove_directory (*i); } } void -MidiPatchManager::refresh() +MidiPatchManager::remove_midnam_files_from_directory(const std::string& directory_path) { - _documents.clear(); - _master_devices_by_model.clear(); - _all_models.clear(); - - Searchpath search_path = midi_patch_search_path (); - Glib::PatternSpec pattern (string("*.midnam")); vector result; + find_files_matching_pattern (result, directory_path, "*.midnam"); - find_matching_files_in_search_path (search_path, pattern, result); + info << string_compose( + P_("Unloading %1 MIDI patch from %2", "Unloading %1 MIDI patches from %2", result.size()), + result.size(), directory_path) + << endmsg; - info << "Loading " << result.size() << " MIDI patches from " << search_path.to_string() << endmsg; + for (vector::const_iterator i = result.begin(); i != result.end(); ++i) { + remove_midi_name_document (*i); + } +} - for (vector::iterator i = result.begin(); i != result.end(); ++i) { - boost::shared_ptr document; - try { - document = boost::shared_ptr(new MIDINameDocument(*i)); - } catch (...) { - error << "Error parsing MIDI patch file " << *i << endmsg; +bool +MidiPatchManager::add_midi_name_document (const std::string& file_path) +{ + boost::shared_ptr document; + try { + document = boost::shared_ptr(new MIDINameDocument(file_path)); + } + catch (...) { + error << string_compose(_("Error parsing MIDI patch file %1"), file_path) + << endmsg; + return false; + } + for (MIDINameDocument::MasterDeviceNamesList::const_iterator device = + document->master_device_names_by_model().begin(); + device != document->master_device_names_by_model().end(); + ++device) { + if (_documents.find(device->first) != _documents.end()) { + warning << string_compose(_("Duplicate MIDI device `%1' in `%2' ignored"), + device->first, + file_path) << endmsg; continue; } - for (MIDINameDocument::MasterDeviceNamesList::const_iterator device = - document->master_device_names_by_model().begin(); - device != document->master_device_names_by_model().end(); - ++device) { - if (_documents.find(device->first) != _documents.end()) { - warning << string_compose(_("Duplicate MIDI device `%1' in `%2' ignored"), - device->first, *i) - << endmsg; - continue; - } - - _documents[device->first] = document; - _master_devices_by_model[device->first] = device->second; - _all_models.insert(device->first); + _documents[device->first] = document; + _master_devices_by_model[device->first] = device->second; + + _all_models.insert(device->first); + const std::string& manufacturer = device->second->manufacturer(); + if (_devices_by_manufacturer.find(manufacturer) == + _devices_by_manufacturer.end()) { + MIDINameDocument::MasterDeviceNamesList empty; + _devices_by_manufacturer.insert(std::make_pair(manufacturer, empty)); } - } + _devices_by_manufacturer[manufacturer].insert( + std::make_pair(device->first, device->second)); - if (_session) { - add_session_patches (); + // TODO: handle this gracefully. + assert(_documents.count(device->first) == 1); + assert(_master_devices_by_model.count(device->first) == 1); } + return true; } -void -MidiPatchManager::session_going_away () +bool +MidiPatchManager::remove_midi_name_document (const std::string& file_path) { - SessionHandlePtr::session_going_away (); - refresh (); + bool removed = false; + for (MidiNameDocuments::iterator i = _documents.begin(); i != _documents.end();) { + if (i->second->file_path() == file_path) { + + boost::shared_ptr document = i->second; + + info << string_compose(_("Removing MIDI patch file %1"), file_path) << endmsg; + + _documents.erase(i++); + + for (MIDINameDocument::MasterDeviceNamesList::const_iterator device = + document->master_device_names_by_model().begin(); + device != document->master_device_names_by_model().end(); + ++device) { + + _master_devices_by_model.erase(device->first); + + _all_models.erase(device->first); + + const std::string& manufacturer = device->second->manufacturer(); + + _devices_by_manufacturer[manufacturer].erase(device->first); + } + removed = true; + } else { + ++i; + } + } + return removed; }