void ModifyDeviceCommand::unexecute() { Device *device = m_studio->getDevice(m_device); if (!device) { std::cerr << "ERROR: ModifyDeviceCommand::unexecute(): no such device as " << m_device << std::endl; return; } MidiDevice *midiDevice = dynamic_cast<MidiDevice *>(device); if (!midiDevice) { std::cerr << "ERROR: ModifyDeviceCommand::unexecute(): device " << m_device << " is not a MIDI device" << std::endl; return; } if (m_rename) midiDevice->setName(m_oldName); midiDevice->replaceBankList(m_oldBankList); midiDevice->replaceProgramList(m_oldProgramList); midiDevice->replaceControlParameters(m_oldControlList); midiDevice->replaceKeyMappingList(m_oldKeyMappingList); midiDevice->setLibrarian(m_oldLibrarianName, m_oldLibrarianEmail); if (m_changeVariation) midiDevice->setVariationType(m_oldVariationType); InstrumentList instruments = midiDevice->getAllInstruments(); for (size_t i = 0; i < instruments.size(); ++i) { instruments[i]->setProgram(m_oldInstrumentPrograms[i]); } // ??? Instead of this kludge, we should be calling a Studio::hasChanged() // which would then notify all observers (e.g. MIPP) who, in turn, // would update themselves. RosegardenMainWindow::self()->uiUpdateKludge(); }
void ModifyDeviceCommand::execute() { Device *device = m_studio->getDevice(m_device); if (!device) { std::cerr << "ERROR: ModifyDeviceCommand::execute(): no such device as " << m_device << std::endl; return; } MidiDevice *midiDevice = dynamic_cast<MidiDevice *>(device); if (!midiDevice) { std::cerr << "ERROR: ModifyDeviceCommand::execute(): device " << m_device << " is not a MIDI device" << std::endl; return; } // Save Original Values for Undo // ??? Really wish we could just m_oldDevice = *(midiDevice). See below. m_oldName = midiDevice->getName(); m_oldBankList = midiDevice->getBanks(); m_oldProgramList = midiDevice->getPrograms(); m_oldControlList = midiDevice->getControlParameters(); m_oldKeyMappingList = midiDevice->getKeyMappings(); m_oldLibrarianName = midiDevice->getLibrarianName(); m_oldLibrarianEmail = midiDevice->getLibrarianEmail(); m_oldVariationType = midiDevice->getVariationType(); InstrumentList instruments = midiDevice->getAllInstruments(); for (size_t i = 0; i < instruments.size(); ++i) { // ??? Preserving just the programs isn't enough. We need // to preserve the rest of the Instrument as well. However, // the auto/fixed channel feature has made it impossible // to safely make copies of Instrument objects. Also, Instrument // has an ID. How should that be handled for undo? ISTM // that we either need to introduce some sort of copyForUndo() // hack to each object, or develop a set of standards for coding // objects that are undo-safe. Sounds like a pretty big project. m_oldInstrumentPrograms.push_back(instruments[i]->getProgram()); } // Make the Changes if (m_changeVariation) midiDevice->setVariationType(m_variationType); if (m_overwrite) { if (m_clearBankAndProgramList) { midiDevice->clearBankList(); midiDevice->clearProgramList(); midiDevice->clearKeyMappingList(); } else { if (m_changeBanks) midiDevice->replaceBankList(m_bankList); if (m_changePrograms) midiDevice->replaceProgramList(m_programList); if (m_changeBanks || m_changePrograms) { // Make sure the instruments make sense. for (size_t i = 0; i < instruments.size(); ++i) { instruments[i]->pickFirstProgram( midiDevice->isPercussionNumber(i)); } } } if (m_changeKeyMappings) { midiDevice->replaceKeyMappingList(m_keyMappingList); } if (m_rename) midiDevice->setName(m_name); midiDevice->setLibrarian(m_librarianName, m_librarianEmail); } else { if (m_clearBankAndProgramList) { midiDevice->clearBankList(); midiDevice->clearProgramList(); } else { if (m_changeBanks) midiDevice->mergeBankList(m_bankList); if (m_changePrograms) midiDevice->mergeProgramList(m_programList); } if (m_changeKeyMappings) { midiDevice->mergeKeyMappingList(m_keyMappingList); } if (m_rename) { std::string mergeName = midiDevice->getName() + std::string("/") + m_name; midiDevice->setName(mergeName); } } //!!! merge option? if (m_changeControls) { midiDevice->replaceControlParameters(m_controlList); } // ??? Instead of this kludge, we should be calling a Studio::hasChanged() // which would then notify all observers (e.g. MIPP) who, in turn, // would update themselves. RosegardenMainWindow::self()->uiUpdateKludge(); }