void
MIDIInstrumentParameterPanel::updateProgramComboBox()
{
    RG_DEBUG << "updateProgramComboBox()";

    if (!getSelectedInstrument())
        return;

    MidiDevice *md =
            dynamic_cast<MidiDevice *>(getSelectedInstrument()->getDevice());
    if (!md) {
        std::cerr << "WARNING: MIDIInstrumentParameterPanel::updateProgramComboBox(): No MidiDevice for Instrument " << getSelectedInstrument()->getId() << '\n';
        return;
    }

    RG_DEBUG << "updateProgramComboBox(): variation type is " << md->getVariationType();

    MidiBank bank = getSelectedInstrument()->getProgram().getBank();

    ProgramList programs =
            md->getPrograms0thVariation(getSelectedInstrument()->isPercussion(), bank);

    // Remove the programs that have no name.
    programs.erase(std::remove_if(programs.begin(), programs.end(),
                                  MIDIInstrumentParameterPanel::hasNoName),
                   programs.end());

    // If we've got programs, show the Program widgets.
    // Why not "show = (programs.size()>1)"?  Because that would hide the
    // program checkbox which would take away the user's ability to
    // enable/disable program changes.  If we do away with the checkbox
    // in the future, we should re-evaluate this decision.
    bool show = !programs.empty();
    m_programLabel->setVisible(show);
    m_programCheckBox->setVisible(show);
    m_programComboBox->setVisible(show);

    int currentProgram = -1;

    // Compute the current program.
    for (unsigned i = 0; i < programs.size(); ++i) {
        // If the program change is the same...
        if (getSelectedInstrument()->getProgram().getProgram() == programs[i].getProgram()) {
            currentProgram = i;
            break;
        }
    }

    // If the programs have changed, we need to repopulate the combobox.
    if (!partialCompareWithName(programs, m_programs))
    {
        // Update the cache.
        m_programs = programs;

        // Copy from m_programs to m_programComboBox.
        m_programComboBox->clear();
        for (unsigned i = 0; i < m_programs.size(); ++i) {
            m_programComboBox->addItem(QObject::tr("%1. %2")
                                       .arg(m_programs[i].getProgram() + 1)
                                       .arg(QObject::tr(m_programs[i].getName().c_str())));
        }
    }

    m_programComboBox->setEnabled(getSelectedInstrument()->sendsProgramChange());

#if 0
// ??? This is a pretty nifty idea, but unfortunately, it requires
//     that we maintain a bogus combobox entry.  For now, we'll go
//     with the simpler "unselected" approach.

    // If the current program was not found...
    if (currentProgram < 0  &&  !m_programs.empty()) {
        // Format program change and add to combobox.
        MidiByte programChange = getSelectedInstrument()->getProgram().getProgram();
        m_programComboBox.addItem(QString::number(programChange + 1));
        currentProgram = programs.size();
    }
#endif

    // Display the current program.
    m_programComboBox->setCurrentIndex(currentProgram);
}