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();
}
Beispiel #3
0
void MPConfig::mdevViewItemRenamed(QTableWidgetItem* item)
{
    int col = item->column();
    QString s = item->text();
    //printf("MPConfig::mdevViewItemRenamed col:%d txt:%s\n", col, s.toLatin1().constData());
    if (item == 0)
        return;
    switch (col)
    {
        case DEVCOL_DEF_IN_CHANS:
        {
            QString id = item->tableWidget()->item(item->row(), DEVCOL_NO)->text();
            int no = atoi(id.toLatin1().constData()) - 1;
            if (no < 0 || no >= kMaxMidiPorts)
                return;
            midiPorts[no].setDefaultInChannels(((1 << kMaxMidiChannels) - 1) & string2bitmap(s));
            song->update();
        }
            break;
        case DEVCOL_DEF_OUT_CHANS:
        {
            QString id = item->tableWidget()->item(item->row(), DEVCOL_NO)->text();
            int no = atoi(id.toLatin1().constData()) - 1;
            if (no < 0 || no >= kMaxMidiPorts)
                return;
            midiPorts[no].setDefaultOutChannels(((1 << kMaxMidiChannels) - 1) & string2bitmap(s));
            song->update();
        }
            break;
        case DEVCOL_NAME:
        {
            QString id = item->tableWidget()->item(item->row(), DEVCOL_NO)->text();
            int no = atoi(id.toLatin1().constData()) - 1;
            if (no < 0 || no >= kMaxMidiPorts)
                return;

            MidiPort* port = &midiPorts[no];
            MidiDevice* dev = port->device();
            // Only Jack midi devices.
            if (!dev || dev->deviceType() != MidiDevice::JACK_MIDI)
                return;
            if (dev->name() == s)
                return;

            if (midiDevices.find(s))
            {
                QMessageBox::critical(this,
                        tr("LOS: bad device name"),
                        tr("please choose a unique device name"),
                        QMessageBox::Ok,
                        Qt::NoButton,
                        Qt::NoButton);
                songChanged(-1);
                return;
            }
            dev->setName(s);
            song->update();
        }
            break;
        default:
            //printf("MPConfig::mdevViewItemRenamed unknown column clicked col:%d txt:%s\n", col, s.toLatin1().constData());
            break;
    }
}