X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fmidi_patch_manager.cc;h=ab93b173066d46a71cb70c6921a3c5ddf7d1b077;hb=0f20819c8643974ce6d52fc1dc7ec3a18877d05b;hp=c6e70b2a6cd096dffe58d58b3694ad58329ec697;hpb=76d43487da0fab3e0fceae4d091859b3d495562e;p=ardour.git diff --git a/libs/ardour/midi_patch_manager.cc b/libs/ardour/midi_patch_manager.cc index c6e70b2a6c..ab93b17306 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,26 +41,138 @@ MidiPatchManager* MidiPatchManager::_manager = 0; MidiPatchManager::MidiPatchManager () { + 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); - refresh (); + 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); + } } bool -MidiPatchManager::add_midi_name_document (const std::string& file_path) +MidiPatchManager::add_custom_midnam (const std::string& id, const std::string& midnam) +{ + boost::shared_ptr document; + document = boost::shared_ptr(new MIDINameDocument()); + XMLTree mxml; + if (mxml.read_buffer (midnam, true)) { + if (0 == document->set_state (mxml, *mxml.root())) { + document->set_file_path ("custom:" + id); + add_midi_name_document (document); + return true; + } + } + return false; +} + +bool +MidiPatchManager::remove_custom_midnam (const std::string& id) +{ + return remove_midi_name_document ("custom:" + id); +} + +bool +MidiPatchManager::update_custom_midnam (const std::string& id, const std::string& midnam) +{ + remove_midi_name_document ("custom:" + id, false); + return add_custom_midnam (id, midnam); +} + +void +MidiPatchManager::add_midnam_files_from_directory(const std::string& directory_path) +{ + vector result; + find_files_matching_pattern (result, directory_path, "*.midnam"); + + info << string_compose( + P_("Loading %1 MIDI patch from %2", "Loading %1 MIDI patches from %2", result.size()), + result.size(), directory_path) + << endmsg; + + for (vector::const_iterator i = result.begin(); i != result.end(); ++i) { + load_midi_name_document (*i); + } +} + +void +MidiPatchManager::remove_search_path (const Searchpath& search_path) +{ + for (Searchpath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) { + + if (!_search_path.contains(*i)) { + continue; + } + + remove_midnam_files_from_directory(*i); + + _search_path.remove_directory (*i); + } +} + +void +MidiPatchManager::remove_midnam_files_from_directory(const std::string& directory_path) +{ + vector result; + find_files_matching_pattern (result, directory_path, "*.midnam"); + + info << string_compose( + P_("Unloading %1 MIDI patch from %2", "Unloading %1 MIDI patches from %2", result.size()), + result.size(), directory_path) + << endmsg; + + for (vector::const_iterator i = result.begin(); i != result.end(); ++i) { + remove_midi_name_document (*i); + } +} + +bool +MidiPatchManager::load_midi_name_document (const std::string& file_path) { boost::shared_ptr document; try { document = boost::shared_ptr(new MIDINameDocument(file_path)); } catch (...) { - error << "Error parsing MIDI patch file " << file_path << endmsg; + error << string_compose(_("Error parsing MIDI patch file %1"), file_path) + << endmsg; return false; } + return add_midi_name_document (document); +} + +boost::shared_ptr +MidiPatchManager::document_by_model(std::string model_name) const +{ + MidiNameDocuments::const_iterator i = _documents.find (model_name); + if (i != _documents.end ()) { + return i->second; + } + return boost::shared_ptr (); +} + +bool +MidiPatchManager::add_midi_name_document (boost::shared_ptr document) +{ + bool added = false; for (MIDINameDocument::MasterDeviceNamesList::const_iterator device = document->master_device_names_by_model().begin(); device != document->master_device_names_by_model().end(); @@ -70,7 +180,7 @@ MidiPatchManager::add_midi_name_document (const std::string& file_path) if (_documents.find(device->first) != _documents.end()) { warning << string_compose(_("Duplicate MIDI device `%1' in `%2' ignored"), device->first, - file_path) << endmsg; + document->file_path()) << endmsg; continue; } @@ -87,69 +197,51 @@ MidiPatchManager::add_midi_name_document (const std::string& file_path) _devices_by_manufacturer[manufacturer].insert( std::make_pair(device->first, device->second)); + added = true; // TODO: handle this gracefully. assert(_documents.count(device->first) == 1); assert(_master_devices_by_model.count(device->first) == 1); } - return true; -} -void -MidiPatchManager::add_session_patches () -{ - if (!_session) { - return; + if (added) { + PatchesChanged(); /* EMIT SIGNAL */ } + return added; +} - std::string path_to_patches = _session->session_directory().midi_patch_path(); - - if (!Glib::file_test (path_to_patches, Glib::FILE_TEST_EXISTS)) { - return; - } - - assert (Glib::file_test (path_to_patches, Glib::FILE_TEST_IS_DIR)); - - vector result; +bool +MidiPatchManager::remove_midi_name_document (const std::string& file_path, bool emit_signal) +{ + bool removed = false; + for (MidiNameDocuments::iterator i = _documents.begin(); i != _documents.end();) { + if (i->second->file_path() == file_path) { - find_files_matching_pattern (result, path_to_patches, "*.midnam"); + boost::shared_ptr document = i->second; - info << "Loading " << result.size() << " MIDI patches from " << path_to_patches << endmsg; + info << string_compose(_("Removing MIDI patch file %1"), file_path) << endmsg; - for (vector::iterator i = result.begin(); i != result.end(); ++i) { - add_midi_name_document(*i); - } -} + _documents.erase(i++); -void -MidiPatchManager::refresh() -{ - _documents.clear(); - _master_devices_by_model.clear(); - _all_models.clear(); - _devices_by_manufacturer.clear(); + for (MIDINameDocument::MasterDeviceNamesList::const_iterator device = + document->master_device_names_by_model().begin(); + device != document->master_device_names_by_model().end(); + ++device) { - Searchpath search_path = midi_patch_search_path (); - vector result; + _master_devices_by_model.erase(device->first); - find_files_matching_pattern (result, search_path, "*.midnam"); + _all_models.erase(device->first); - info << "Loading " << result.size() << " MIDI patches from " << search_path.to_string() << endmsg; + const std::string& manufacturer = device->second->manufacturer(); - for (vector::iterator i = result.begin(); i != result.end(); ++i) { - add_midi_name_document (*i); + _devices_by_manufacturer[manufacturer].erase(device->first); + } + removed = true; + } else { + ++i; + } } - - if (_session) { - add_session_patches (); + if (removed && emit_signal) { + PatchesChanged(); /* EMIT SIGNAL */ } -} - -void -MidiPatchManager::session_going_away () -{ - SessionHandlePtr::session_going_away (); - _documents.clear(); - _master_devices_by_model.clear(); - _all_models.clear(); - _devices_by_manufacturer.clear(); + return removed; }