+ assert(a_node.name() == "CustomDeviceMode");
+
+ _name = a_node.property("Name")->value();
+
+ boost::shared_ptr<XMLSharedNodeList> channel_name_set_assignments =
+ tree.find("//ChannelNameSetAssign", (XMLNode *)&a_node);
+ for(XMLSharedNodeList::const_iterator i = channel_name_set_assignments->begin();
+ i != channel_name_set_assignments->end();
+ ++i) {
+ int channel = atoi((*i)->property("Channel")->value().c_str());
+ string name_set = (*i)->property("NameSet")->value();
+ assert( 1 <= channel && channel <= 16 );
+ _channel_name_set_assignments[channel - 1] = name_set;
+ }
+ return 0;
+}
+
+XMLNode&
+CustomDeviceMode::get_state(void)
+{
+ XMLNode* custom_device_mode = new XMLNode("CustomDeviceMode");
+ custom_device_mode->add_property("Name", _name);
+ XMLNode* channel_name_set_assignments =
+ custom_device_mode->add_child("ChannelNameSetAssignments");
+ for (int i = 0; i < 15 && !_channel_name_set_assignments[i].empty(); i++) {
+ XMLNode* channel_name_set_assign =
+ channel_name_set_assignments->add_child("ChannelNameSetAssign");
+ channel_name_set_assign->add_property("Channel", i + 1);
+ channel_name_set_assign->add_property("NameSet", _channel_name_set_assignments[i]);
+ }
+
+ return *custom_device_mode;
+}
+
+boost::shared_ptr<CustomDeviceMode>
+MasterDeviceNames::custom_device_mode_by_name(std::string mode_name)
+{
+ // can't assert this, since in many of the patch files the mode name is empty
+ //assert(mode_name != "");
+ return _custom_device_modes[mode_name];
+}
+
+boost::shared_ptr<ChannelNameSet>
+MasterDeviceNames::channel_name_set_by_device_mode_and_channel(std::string mode, uint8_t channel)
+{
+ boost::shared_ptr<CustomDeviceMode> cdm = custom_device_mode_by_name(mode);
+ boost::shared_ptr<ChannelNameSet> cns = _channel_name_sets[cdm->channel_name_set_name_by_channel(channel)];
+ return cns;
+}
+
+boost::shared_ptr<Patch>
+MasterDeviceNames::find_patch(std::string mode, uint8_t channel, PatchPrimaryKey& key)
+{
+ return channel_name_set_by_device_mode_and_channel(mode, channel)->find_patch(key);
+}
+
+int
+MasterDeviceNames::set_state(const XMLTree& tree, const XMLNode& a_node)
+{
+ // Manufacturer
+ boost::shared_ptr<XMLSharedNodeList> manufacturer = tree.find("//Manufacturer");
+ assert(manufacturer->size() == 1);
+ _manufacturer = manufacturer->front()->children().front()->content();
+
+ // Models
+ boost::shared_ptr<XMLSharedNodeList> models = tree.find("//Model");
+ assert(models->size() >= 1);
+ for (XMLSharedNodeList::iterator i = models->begin();
+ i != models->end();
+ ++i) {
+ const XMLNodeList& contents = (*i)->children();
+ assert(contents.size() == 1);
+ XMLNode * content = *(contents.begin());
+ assert(content->is_content());
+ _models.push_back(content->content());
+ }
+
+ // CustomDeviceModes
+ boost::shared_ptr<XMLSharedNodeList> custom_device_modes = tree.find("//CustomDeviceMode");
+ for (XMLSharedNodeList::iterator i = custom_device_modes->begin();
+ i != custom_device_modes->end();
+ ++i) {
+ boost::shared_ptr<CustomDeviceMode> custom_device_mode(new CustomDeviceMode());
+ custom_device_mode->set_state(tree, *(*i));
+
+ _custom_device_modes[custom_device_mode->name()] = custom_device_mode;
+ _custom_device_mode_names.push_back(custom_device_mode->name());
+ }
+
+ // ChannelNameSets
+ boost::shared_ptr<XMLSharedNodeList> channel_name_sets = tree.find("//ChannelNameSet");
+ for (XMLSharedNodeList::iterator i = channel_name_sets->begin();
+ i != channel_name_sets->end();
+ ++i) {
+ boost::shared_ptr<ChannelNameSet> channel_name_set(new ChannelNameSet());
+ channel_name_set->set_state(tree, *(*i));
+ _channel_name_sets[channel_name_set->name()] = channel_name_set;
+ }
+
+ // NoteNameLists
+ boost::shared_ptr<XMLSharedNodeList> note_name_lists = tree.find("//NoteNameList");
+ for (XMLSharedNodeList::iterator i = note_name_lists->begin();
+ i != note_name_lists->end();
+ ++i) {
+ boost::shared_ptr<NoteNameList> note_name_list(new NoteNameList());
+ note_name_list->set_state (tree, *(*i));
+ _note_name_lists.push_back(note_name_list);
+ }
+
+ // global/post-facto PatchNameLists
+ boost::shared_ptr<XMLSharedNodeList> patch_name_lists = tree.find("/child::MIDINameDocument/child::MasterDeviceNames/child::PatchNameList");
+ for (XMLSharedNodeList::iterator i = patch_name_lists->begin();
+ i != patch_name_lists->end();
+ ++i) {
+
+ PatchBank::PatchNameList patch_name_list;
+ const XMLNodeList patches = (*i)->children();
+
+ for (XMLNodeList::const_iterator p = patches.begin(); p != patches.end(); ++p) {
+ boost::shared_ptr<Patch> patch (new Patch ());
+ patch->set_state(tree, *(*p));
+ patch_name_list.push_back(patch);
+ }
+
+ if (!patch_name_list.empty()) {
+ _patch_name_lists[(*i)->property ("Name")->value()] = patch_name_list;
+ }
+ }
+
+ /* now traverse patches and hook up anything that used UsePatchNameList
+ * to the right patch list
+ */
+
+ for (ChannelNameSets::iterator cns = _channel_name_sets.begin(); cns != _channel_name_sets.end(); ++cns) {
+ ChannelNameSet::PatchBanks pbs = cns->second->patch_banks();
+ PatchNameLists::iterator p;
+
+ for (ChannelNameSet::PatchBanks::iterator pb = pbs.begin(); pb != pbs.end(); ++pb) {
+ std::string pln = (*pb)->patch_list_name();
+ if (!pln.empty()) {
+ if ((p = _patch_name_lists.find (pln)) != _patch_name_lists.end()) {
+ if ((*pb)->set_patch_name_list (p->second)) {
+ return -1;
+ }
+ cns->second->use_patch_name_list (p->second);
+ } else {
+ error << string_compose ("Patch list name %1 was not found - patch file ignored", pln) << endmsg;
+ return -1;
+ }
+ }
+ }
+
+ }
+
+ return 0;
+}
+
+XMLNode&
+MasterDeviceNames::get_state(void)
+{
+ static XMLNode nothing("<nothing>");
+ return nothing;
+}
+
+MIDINameDocument::MIDINameDocument (const string& filename)
+{
+ if (!_document.read (filename)) {
+ throw failed_constructor ();
+ }
+
+ set_state (_document, *_document.root());
+}
+
+int
+MIDINameDocument::set_state (const XMLTree& tree, const XMLNode& a_node)
+{
+ // Author
+
+ boost::shared_ptr<XMLSharedNodeList> author = tree.find("//Author");
+ if (author->size() < 1) {
+ error << "No author information in MIDNAM file" << endmsg;
+ return -1;
+ }
+
+ if (author->front()->children().size() > 0) {
+ _author = author->front()->children().front()->content();
+ }
+
+ // MasterDeviceNames
+
+ boost::shared_ptr<XMLSharedNodeList> master_device_names_list = tree.find ("//MasterDeviceNames");
+
+ for (XMLSharedNodeList::iterator i = master_device_names_list->begin();
+ i != master_device_names_list->end();
+ ++i) {
+ boost::shared_ptr<MasterDeviceNames> master_device_names(new MasterDeviceNames());
+
+ if (master_device_names->set_state(tree, *(*i))) {
+ return -1;
+ }
+
+ for (MasterDeviceNames::Models::const_iterator model = master_device_names->models().begin();
+ model != master_device_names->models().end();
+ ++model) {
+ _master_device_names_list.insert(
+ std::pair<std::string, boost::shared_ptr<MasterDeviceNames> >
+ (*model, master_device_names));
+
+ _all_models.push_back(*model);
+ }
+ }
+