void TrackParameterBox::updateInstrument(const Instrument *instrument) { // As with the Device field above, this will rarely change and it is // expensive to clear and reload. So, we should cache enough info to // detect a real change. This would be Instrument names and IDs. const DeviceId deviceId = instrument->getDevice()->getId(); const Device &device = *(m_doc->getStudio().getDevice(deviceId)); const InstrumentList instrumentList = device.getPresentationInstruments(); // Generate local instrument name and ID lists to compare against the // members. std::vector<InstrumentId> instrumentIds; std::vector<QString> instrumentNames; // For each instrument for (size_t instrumentIndex = 0; instrumentIndex < instrumentList.size(); ++instrumentIndex) { const Instrument &loopInstrument = *(instrumentList[instrumentIndex]); instrumentIds.push_back(loopInstrument.getId()); QString instrumentName(QObject::tr(loopInstrument.getName().c_str())); QString programName( QObject::tr(loopInstrument.getProgramName().c_str())); if (loopInstrument.getType() == Instrument::SoftSynth) { instrumentName.replace(QObject::tr("Synth plugin"), ""); programName = ""; AudioPluginInstance *plugin = instrument->getPlugin(Instrument::SYNTH_PLUGIN_POSITION); if (plugin) programName = strtoqstr(plugin->getDisplayName()); } if (programName != "") instrumentName += " (" + programName + ")"; // cut off the redundant eg. "General MIDI Device" that appears in the // combo right above here anyway instrumentName = instrumentName.mid( instrumentName.indexOf("#"), instrumentName.length()); instrumentNames.push_back(instrumentName); } // If there has been an actual change if (instrumentIds != m_instrumentIds2 || instrumentNames != m_instrumentNames2) { // Update the cache. m_instrumentIds2 = instrumentIds; m_instrumentNames2 = instrumentNames; // Reload the combobox m_instrument->clear(); // For each instrument, add the name to the combobox. // ??? If we used a QStringList, we could just call addItems(). for (size_t instrumentIndex = 0; instrumentIndex < m_instrumentNames2.size(); ++instrumentIndex) { m_instrument->addItem(m_instrumentNames2[instrumentIndex]); } } // Find the current instrument in the instrument ID list. const InstrumentId instrumentId = instrument->getId(); // Assume not found. int currentIndex = -1; // For each Instrument for (size_t instrumentIndex = 0; instrumentIndex < m_instrumentIds2.size(); ++instrumentIndex) { // If this is the selected Instrument if (m_instrumentIds2[instrumentIndex] == instrumentId) { currentIndex = instrumentIndex; break; } } // Set the index. m_instrument->setCurrentIndex(currentIndex); }
void ManageMetronomeDialog::populate(int deviceIndex) { m_metronomeInstrument->clear(); DeviceList *devices = m_doc->getStudio().getDevices(); DeviceListConstIterator it; int count = 0; Device *dev = 0; for (it = devices->begin(); it != devices->end(); it++) { dev = *it; if (!isSuitable(dev)) continue; if (count == deviceIndex) break; count++; } // sanity if (count < 0 || dev == 0 || !isSuitable(dev)) { return ; } // populate instrument list InstrumentList list = dev->getPresentationInstruments(); InstrumentList::iterator iit; const MidiMetronome *metronome = getMetronome(dev); // if we've got no metronome against this device then create one if (metronome == 0) { InstrumentId id = SystemInstrumentBase; for (iit = list.begin(); iit != list.end(); ++iit) { if ((*iit)->isPercussion()) { id = (*iit)->getId(); break; } } setMetronome(dev, MidiMetronome(id)); metronome = getMetronome(dev); } // metronome should now be set but we still check it if (metronome) { int position = 0; int count = 0; for (iit = list.begin(); iit != list.end(); ++iit) { QString iname(QObject::tr((*iit)->getName().c_str())); QString ipname((*iit)->getLocalizedPresentationName()); QString programName(QObject::tr((*iit)->getProgramName().c_str())); QString text; if ((*iit)->getType() == Instrument::SoftSynth) { iname.replace(QObject::tr("Synth plugin "), ""); programName = ""; AudioPluginInstance *plugin = (*iit)->getPlugin (Instrument::SYNTH_PLUGIN_POSITION); if (plugin) programName = strtoqstr(plugin->getDisplayName()); } else { iname = ipname; } if (programName != "") { text = tr("%1 (%2)").arg(iname).arg(programName); } else { text = iname; } m_metronomeInstrument->addItem(text); if ((*iit)->getId() == metronome->getInstrument()) { position = count; } count++; } m_metronomeInstrument->setCurrentIndex(position); m_barPitch = metronome->getBarPitch(); m_beatPitch = metronome->getBeatPitch(); m_subBeatPitch = metronome->getSubBeatPitch(); slotPitchSelectorChanged(0); m_metronomeResolution->setCurrentIndex(metronome->getDepth()); m_metronomeBarVely->setValue(metronome->getBarVelocity()); m_metronomeBeatVely->setValue(metronome->getBeatVelocity()); m_metronomeSubBeatVely->setValue(metronome->getSubBeatVelocity()); m_playEnabled->setChecked(m_doc->getComposition().usePlayMetronome()); m_recordEnabled->setChecked(m_doc->getComposition().useRecordMetronome()); slotResolutionChanged(metronome->getDepth()); } }
// ??? Break this stuff off into an InstrumentPopup class. This class is too // big. void TrackButtons::populateInstrumentPopup(Instrument *thisTrackInstr, QMenu* instrumentPopup) { // pixmaps for icons to show connection states as variously colored boxes // ??? Factor out the icon-related stuff to make this routine clearer. // getIcon(Instrument *) would be ideal, but might not be easy. // getIcon(Device *) would also be needed. static QPixmap connectedPixmap, unconnectedPixmap, connectedUsedPixmap, unconnectedUsedPixmap, connectedSelectedPixmap, unconnectedSelectedPixmap; static bool havePixmaps = false; if (!havePixmaps) { IconLoader il; connectedPixmap = il.loadPixmap("connected"); connectedUsedPixmap = il.loadPixmap("connected-used"); connectedSelectedPixmap = il.loadPixmap("connected-selected"); unconnectedPixmap = il.loadPixmap("unconnected"); unconnectedUsedPixmap = il.loadPixmap("unconnected-used"); unconnectedSelectedPixmap = il.loadPixmap("unconnected-selected"); havePixmaps = true; } Composition &comp = m_doc->getComposition(); // clear the popup instrumentPopup->clear(); QMenu *currentSubMenu = 0; // position index int count = 0; int currentDevId = -1; // Get the list Studio &studio = m_doc->getStudio(); InstrumentList list = studio.getPresentationInstruments(); // For each instrument for (InstrumentList::iterator it = list.begin(); it != list.end(); ++it) { if (!(*it)) continue; // sanity check // get the Localized instrument name, with the string hackery performed // in Instrument QString iname((*it)->getLocalizedPresentationName()); // translate the program name // // Note we are converting the string from std to Q back to std then to // C. This is obviously ridiculous, but the fact that we have programName // here at all makes me think it exists as some kind of necessary hack // to coax tr() into behaving nicely. I decided to change it as little // as possible to get it to compile, and not refactor this down to the // simplest way to call tr() on a C string. QString programName(strtoqstr((*it)->getProgramName())); programName = QObject::tr(programName.toStdString().c_str()); Device *device = (*it)->getDevice(); DeviceId devId = device->getId(); bool connectedIcon = false; // Determine the proper program name and whether it is connected if ((*it)->getType() == Instrument::SoftSynth) { programName = ""; AudioPluginInstance *plugin = (*it)->getPlugin(Instrument::SYNTH_PLUGIN_POSITION); if (plugin) { // we don't translate any plugin program names or other texts programName = strtoqstr(plugin->getDisplayName()); connectedIcon = (plugin->getIdentifier() != ""); } } else if ((*it)->getType() == Instrument::Audio) { connectedIcon = true; } else { QString conn = RosegardenSequencer::getInstance()-> getConnection(devId); connectedIcon = (conn != ""); } // These two are for selecting the correct icon to display. bool instrUsedByMe = false; bool instrUsedByAnyone = false; if (thisTrackInstr && thisTrackInstr->getId() == (*it)->getId()) { instrUsedByMe = true; instrUsedByAnyone = true; } // If we have switched to a new device, we'll create a new submenu if (devId != (DeviceId)(currentDevId)) { currentDevId = int(devId); // For selecting the correct icon to display. bool deviceUsedByAnyone = false; if (instrUsedByMe) deviceUsedByAnyone = true; else { for (Composition::trackcontainer::iterator tit = comp.getTracks().begin(); tit != comp.getTracks().end(); ++tit) { if (tit->second->getInstrument() == (*it)->getId()) { instrUsedByAnyone = true; deviceUsedByAnyone = true; break; } Instrument *instr = studio.getInstrumentById(tit->second->getInstrument()); if (instr && (instr->getDevice()->getId() == devId)) { deviceUsedByAnyone = true; } } } QIcon icon (connectedIcon ? (deviceUsedByAnyone ? connectedUsedPixmap : connectedPixmap) : (deviceUsedByAnyone ? unconnectedUsedPixmap : unconnectedPixmap)); // Create a submenu for this device QMenu *subMenu = new QMenu(instrumentPopup); subMenu->setMouseTracking(true); subMenu->setIcon(icon); // Not needed so long as AA_DontShowIconsInMenus is false. //subMenu->menuAction()->setIconVisibleInMenu(true); // Menu title QString deviceName = QObject::tr(device->getName().c_str()); subMenu->setTitle(deviceName); // QObject name subMenu->setObjectName(deviceName); // Add the submenu to the popup menu instrumentPopup->addMenu(subMenu); // Connect the submenu to slotInstrumentSelected() connect(subMenu, SIGNAL(triggered(QAction*)), this, SLOT(slotInstrumentSelected(QAction*))); currentSubMenu = subMenu; } else if (!instrUsedByMe) {