/* Rosegarden A MIDI and audio sequencer and musical notation editor. This program is Copyright 2000-2008 Guillaume Laurent , Chris Cannam , Richard Bown The moral rights of Guillaume Laurent, Chris Cannam, and Richard Bown to claim authorship of this work have been asserted. Other copyrights also apply to some parts of this work. Please see the AUTHORS file and individual file headers for details. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. See the file COPYING included with this distribution for more information. */ #include "TrackButtons.h" #include #include #include #include "misc/Debug.h" #include "misc/Strings.h" #include "base/AudioPluginInstance.h" #include "base/Composition.h" #include "base/Device.h" #include "base/Instrument.h" #include "base/MidiProgram.h" #include "base/Studio.h" #include "base/Track.h" #include "commands/segment/RenameTrackCommand.h" #include "document/RosegardenGUIDoc.h" #include "document/MultiViewCommandHistory.h" #include "gui/application/RosegardenGUIApp.h" #include "gui/general/GUIPalette.h" #include "gui/kdeext/KLedButton.h" #include "sound/AudioFileManager.h" #include "sound/PluginIdentifier.h" #include "TrackLabel.h" #include "TrackVUMeter.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace Rosegarden { TrackButtons::TrackButtons(RosegardenGUIDoc* doc, unsigned int trackCellHeight, unsigned int trackLabelWidth, bool showTrackLabels, int overallHeight, TQWidget* parent, const char* name, WFlags f) : TQFrame(parent, name, f), m_doc(doc), m_layout(new TQVBoxLayout(this)), m_recordSigMapper(new TQSignalMapper(TQT_TQOBJECT(this))), m_muteSigMapper(new TQSignalMapper(TQT_TQOBJECT(this))), m_clickedSigMapper(new TQSignalMapper(TQT_TQOBJECT(this))), m_instListSigMapper(new TQSignalMapper(TQT_TQOBJECT(this))), m_tracks(doc->getComposition().getNbTracks()), m_offset(4), m_cellSize(trackCellHeight), m_borderGap(1), m_trackLabelWidth(trackLabelWidth), m_popupItem(0), m_lastSelected( -1) { setFrameStyle(Plain); // when we create the widget, what are we looking at? if (showTrackLabels) m_trackInstrumentLabels = TrackLabel::ShowTrack; else m_trackInstrumentLabels = TrackLabel::ShowInstrument; // Set the spacing between vertical elements // m_layout->setSpacing(m_borderGap); // Now draw the buttons and labels and meters // makeButtons(); m_layout->addStretch(20); connect(m_recordSigMapper, TQT_SIGNAL(mapped(int)), this, TQT_SLOT(slotToggleRecordTrack(int))); connect(m_muteSigMapper, TQT_SIGNAL(mapped(int)), this, TQT_SLOT(slotToggleMutedTrack(int))); // connect signal mappers connect(m_instListSigMapper, TQT_SIGNAL(mapped(int)), this, TQT_SLOT(slotInstrumentSelection(int))); connect(m_clickedSigMapper, TQT_SIGNAL(mapped(int)), this, TQT_SIGNAL(trackSelected(int))); // // Populate instrument popup menu just once at start-up // // // populateInstrumentPopup(); // We have to force the height for the moment // setMinimumHeight(overallHeight); } TrackButtons::~TrackButtons() {} void TrackButtons::makeButtons() { if (!m_doc) return ; // Create a horizontal box for each track // plus the two buttons // unsigned int nbTracks = m_doc->getComposition().getNbTracks(); for (unsigned int i = 0; i < nbTracks; ++i) { Track *track = m_doc->getComposition().getTrackByPosition(i); if (track) { TQFrame *trackHBox = makeButton(track->getId()); if (trackHBox) { m_layout->addWidget(trackHBox); m_trackHBoxes.push_back(trackHBox); } } } populateButtons(); } void TrackButtons::setButtonMapping(TQObject* obj, TrackId trackId) { m_clickedSigMapper->setMapping(obj, trackId); m_instListSigMapper->setMapping(obj, trackId); } void TrackButtons::populateButtons() { Instrument *ins = 0; Track *track; for (unsigned int i = 0; i < m_trackLabels.size(); ++i) { track = m_doc->getComposition().getTrackByPosition(i); if (track) { ins = m_doc->getStudio().getInstrumentById(track->getInstrument()); // Set mute button from track // if (track->isMuted()) m_muteLeds[i]->off(); else m_muteLeds[i]->on(); // Set record button from track // bool recording = m_doc->getComposition().isTrackRecording(track->getId()); setRecordTrack(track->getPosition(), recording); // reset track tokens m_trackLabels[i]->setId(track->getId()); setButtonMapping(TQT_TQOBJECT(m_trackLabels[i]), track->getId()); m_trackLabels[i]->setPosition(i); } if (ins) { m_trackLabels[i]->getInstrumentLabel()->setText (strtoqstr(ins->getPresentationName())); if (ins->sendsProgramChange()) { m_trackLabels[i]->setAlternativeLabel(strtoqstr(ins->getProgramName())); } } else { m_trackLabels[i]->getInstrumentLabel()->setText(i18n("")); } m_trackLabels[i]->update(); } } std::vector TrackButtons::mutedTracks() { std::vector mutedTracks; for (TrackId i = 0; i < m_tracks; i++) { if (m_muteLeds[i]->state() == KLed::Off) mutedTracks.push_back(i); } return mutedTracks; } void TrackButtons::slotToggleMutedTrack(int mutedTrackPos) { RG_DEBUG << "TrackButtons::slotToggleMutedTrack(" << mutedTrackPos << ")\n"; if (mutedTrackPos < 0 || mutedTrackPos > (int)m_tracks ) return ; Track *track = m_doc->getComposition().getTrackByPosition(mutedTrackPos); emit muteButton(track->getId(), !track->isMuted()); // will set the value } void TrackButtons::removeButtons(unsigned int position) { RG_DEBUG << "TrackButtons::removeButtons - " << "deleting track button at position " << position << endl; if (position >= m_trackHBoxes.size()) { RG_DEBUG << "%%%%%%%%% BIG PROBLEM : TrackButtons::removeButtons() was passed a non-existing index\n"; return ; } std::vector::iterator tit = m_trackLabels.begin(); tit += position; m_trackLabels.erase(tit); std::vector::iterator vit = m_trackMeters.begin(); vit += position; m_trackMeters.erase(vit); std::vector::iterator mit = m_muteLeds.begin(); mit += position; m_muteLeds.erase(mit); mit = m_recordLeds.begin(); mit += position; m_recordLeds.erase(mit); delete m_trackHBoxes[position]; // deletes all child widgets (button, led, label...) std::vector::iterator it = m_trackHBoxes.begin(); it += position; m_trackHBoxes.erase(it); } void TrackButtons::slotUpdateTracks() { Composition &comp = m_doc->getComposition(); unsigned int newNbTracks = comp.getNbTracks(); Track *track = 0; std::cerr << "TrackButtons::slotUpdateTracks" << std::endl; if (newNbTracks < m_tracks) { for (unsigned int i = m_tracks; i > newNbTracks; --i) removeButtons(i - 1); } else if (newNbTracks > m_tracks) { for (unsigned int i = m_tracks; i < newNbTracks; ++i) { track = m_doc->getComposition().getTrackByPosition(i); if (track) { TQFrame *trackHBox = makeButton(track->getId()); if (trackHBox) { trackHBox->show(); m_layout->insertWidget(i, trackHBox); m_trackHBoxes.push_back(trackHBox); } } else RG_DEBUG << "TrackButtons::slotUpdateTracks - can't find TrackId for position " << i << endl; } } // Set height // for (unsigned int i = 0; i < m_trackHBoxes.size(); ++i) { track = comp.getTrackByPosition(i); if (track) { int multiple = m_doc->getComposition() .getMaxContemporaneousSegmentsOnTrack(track->getId()); if (multiple == 0) multiple = 1; // nasty dupe from makeButton int buttonGap = 8; int vuWidth = 20; int vuSpacing = 2; int labelWidth = m_trackLabelWidth - ((m_cellSize - buttonGap) * 2 + vuSpacing * 2 + vuWidth); m_trackHBoxes[i]->setMinimumSize (labelWidth, m_cellSize * multiple - m_borderGap); m_trackHBoxes[i]->setFixedHeight (m_cellSize * multiple - m_borderGap); } } // Renumber all the labels // for (unsigned int i = 0; i < m_trackLabels.size(); ++i) { track = comp.getTrackByPosition(i); if (track) { m_trackLabels[i]->setId(track->getId()); TQLabel *trackLabel = m_trackLabels[i]->getTrackLabel(); if (track->getLabel() == std::string("")) { Instrument *ins = m_doc->getStudio().getInstrumentById(track->getInstrument()); if (ins && ins->getType() == Instrument::Audio) { trackLabel->setText(i18n("")); } else { trackLabel->setText(i18n("")); } } else { trackLabel->setText(strtoqstr(track->getLabel())); } // RG_DEBUG << "TrackButtons::slotUpdateTracks - set button mapping at pos " // << i << " to track id " << track->getId() << endl; setButtonMapping(TQT_TQOBJECT(m_trackLabels[i]), track->getId()); } } m_tracks = newNbTracks; // Set record status and colour for (unsigned int i = 0; i < m_trackLabels.size(); ++i) { track = comp.getTrackByPosition(i); if (track) { setRecordTrack(i, comp.isTrackRecording(track->getId())); Instrument *ins = m_doc->getStudio().getInstrumentById(track->getInstrument()); if (ins && ins->getType() == Instrument::Audio) { m_recordLeds[i]->setColor (GUIPalette::getColour (GUIPalette::RecordAudioTrackLED)); } else { m_recordLeds[i]->setColor (GUIPalette::getColour (GUIPalette::RecordMIDITrackLED)); } } } // repopulate the buttons populateButtons(); } void TrackButtons::slotToggleRecordTrack(int position) { Composition &comp = m_doc->getComposition(); Track *track = comp.getTrackByPosition(position); bool state = !comp.isTrackRecording(track->getId()); Instrument *instrument = m_doc->getStudio().getInstrumentById (track->getInstrument()); bool audio = (instrument && instrument->getType() == Instrument::Audio); if (audio && state) { try { m_doc->getAudioFileManager().testAudioPath(); } catch (AudioFileManager::BadAudioPathException e) { if (KMessageBox::warningContinueCancel (this, i18n("The audio file path does not exist or is not writable.\nPlease set the audio file path to a valid directory in Document Properties before recording audio.\nWould you like to set it now?"), i18n("Warning"), i18n("Set audio file path")) == KMessageBox::Continue) { RosegardenGUIApp::self()->slotOpenAudioPathSettings(); } } } // can have any number of audio instruments armed, but only one // track armed per instrument. // Need to copy this container, as we're implicitly modifying it // through calls to comp.setTrackRecording Composition::recordtrackcontainer oldRecordTracks = comp.getRecordTracks(); for (Composition::recordtrackcontainer::const_iterator i = oldRecordTracks.begin(); i != oldRecordTracks.end(); ++i) { if (!comp.isTrackRecording(*i)) { // We've already reset this one continue; } Track *otherTrack = comp.getTrackById(*i); if (otherTrack && otherTrack != track) { /* Obsolete code: audio, MIDI and plugin tracks behave the same now. plcl, 06/2006 - Multitrack MIDI recording bool unselect; if (audio) { unselect = (otherTrack->getInstrument() == track->getInstrument()); } else { // our track is not an audio track, check that the // other isn't either Instrument *otherInstrument = m_doc->getStudio().getInstrumentById(otherTrack->getInstrument()); bool otherAudio = (otherInstrument && otherInstrument->getType() == Instrument::Audio); unselect = !otherAudio; } if (unselect) { */ if (otherTrack->getInstrument() == track->getInstrument()) { // found another record track of the same type (and // with the same instrument, if audio): unselect that //!!! should we tell the user, particularly for the //audio case? might seem odd otherwise int otherPos = otherTrack->getPosition(); setRecordTrack(otherPos, false); } } } setRecordTrack(position, state); emit recordButton(track->getId(), state); } void TrackButtons::setRecordTrack(int position, bool state) { setRecordButton(position, state); m_doc->getComposition().setTrackRecording (m_trackLabels[position]->getId(), state); } void TrackButtons::setRecordButton(int position, bool state) { if (position < 0 || position >= (int)m_tracks) return ; KLedButton* led = m_recordLeds[position]; led->setState(state ? KLed::On : KLed::Off); } void TrackButtons::selectLabel(int position) { if (m_lastSelected >= 0 && m_lastSelected < (int)m_trackLabels.size()) { m_trackLabels[m_lastSelected]->setSelected(false); } if (position >= 0 && position < (int)m_trackLabels.size()) { m_trackLabels[position]->setSelected(true); m_lastSelected = position; } } std::vector TrackButtons::getHighlightedTracks() { std::vector retList; for (unsigned int i = 0; i < m_trackLabels.size(); ++i) { if (m_trackLabels[i]->isSelected()) retList.push_back(i); } return retList; } void TrackButtons::slotRenameTrack(TQString newName, TrackId trackId) { m_doc->getCommandHistory()->addCommand (new RenameTrackCommand(&m_doc->getComposition(), trackId, qstrtostr(newName))); changeTrackLabel(trackId, newName); } void TrackButtons::slotSetTrackMeter(float value, int position) { //Composition &comp = m_doc->getComposition(); //Studio &studio = m_doc->getStudio(); //Track *track; for (unsigned int i = 0; i < m_trackMeters.size(); ++i) { if (i == ((unsigned int)position)) { m_trackMeters[i]->setLevel(value); return ; } } } void TrackButtons::slotSetMetersByInstrument(float value, InstrumentId id) { Composition &comp = m_doc->getComposition(); //Studio &studio = m_doc->getStudio(); Track *track; for (unsigned int i = 0; i < m_trackMeters.size(); ++i) { track = comp.getTrackByPosition(i); if (track != 0 && track->getInstrument() == id) { m_trackMeters[i]->setLevel(value); } } } void TrackButtons::slotInstrumentSelection(int trackId) { RG_DEBUG << "TrackButtons::slotInstrumentSelection(" << trackId << ")\n"; Composition &comp = m_doc->getComposition(); Studio &studio = m_doc->getStudio(); int position = comp.getTrackById(trackId)->getPosition(); TQString instrumentName = i18n(""); Track *track = comp.getTrackByPosition(position); Instrument *instrument = 0; if (track != 0) { instrument = studio.getInstrumentById(track->getInstrument()); if (instrument) instrumentName = strtoqstr(instrument->getPresentationName()); } // // populate this instrument widget m_trackLabels[position]->getInstrumentLabel()->setText(instrumentName); // Ensure the instrument name is shown m_trackLabels[position]->showLabel(TrackLabel::ShowInstrument); // Yes, well as we might've changed the Device name in the // Device/Bank dialog then we reload the whole menu here. // TQPopupMenu instrumentPopup(this); populateInstrumentPopup(instrument, &instrumentPopup); // Store the popup item position // m_popupItem = position; instrumentPopup.exec(TQCursor::pos()); // Restore the label back to what it was showing m_trackLabels[position]->showLabel(m_trackInstrumentLabels); // Do this here as well as in slotInstrumentPopupActivated, so as // to restore the correct alternative label even if no other // program was selected from the menu if (track != 0) { instrument = studio.getInstrumentById(track->getInstrument()); if (instrument) { m_trackLabels[position]->getInstrumentLabel()-> setText(strtoqstr(instrument->getPresentationName())); m_trackLabels[position]->clearAlternativeLabel(); if (instrument->sendsProgramChange()) { m_trackLabels[position]->setAlternativeLabel (strtoqstr(instrument->getProgramName())); } } } } void TrackButtons::populateInstrumentPopup(Instrument *thisTrackInstr, TQPopupMenu* instrumentPopup) { static TQPixmap connectedPixmap, unconnectedPixmap, connectedUsedPixmap, unconnectedUsedPixmap, connectedSelectedPixmap, unconnectedSelectedPixmap; static bool havePixmaps = false; if (!havePixmaps) { TQString pixmapDir = TDEGlobal::dirs()->findResource("appdata", "pixmaps/"); connectedPixmap.load (TQString("%1/misc/connected.xpm").arg(pixmapDir)); connectedUsedPixmap.load (TQString("%1/misc/connected-used.xpm").arg(pixmapDir)); connectedSelectedPixmap.load (TQString("%1/misc/connected-selected.xpm").arg(pixmapDir)); unconnectedPixmap.load (TQString("%1/misc/unconnected.xpm").arg(pixmapDir)); unconnectedUsedPixmap.load (TQString("%1/misc/unconnected-used.xpm").arg(pixmapDir)); unconnectedSelectedPixmap.load (TQString("%1/misc/unconnected-selected.xpm").arg(pixmapDir)); havePixmaps = true; } Composition &comp = m_doc->getComposition(); Studio &studio = m_doc->getStudio(); // clear the popup instrumentPopup->clear(); std::vector instrumentSubMenus; // position index int i = 0; // Get the list InstrumentList list = studio.getPresentationInstruments(); InstrumentList::iterator it; int currentDevId = -1; bool deviceUsedByAnyone = false; for (it = list.begin(); it != list.end(); it++) { if (! (*it)) continue; // sanity check TQString iname(strtoqstr((*it)->getPresentationName())); TQString pname(strtoqstr((*it)->getProgramName())); Device *device = (*it)->getDevice(); DeviceId devId = device->getId(); bool connected = false; if ((*it)->getType() == Instrument::SoftSynth) { pname = ""; AudioPluginInstance *plugin = (*it)->getPlugin (Instrument::SYNTH_PLUGIN_POSITION); if (plugin) { pname = strtoqstr(plugin->getProgram()); TQString identifier = strtoqstr(plugin->getIdentifier()); if (identifier != "") { connected = true; TQString type, soName, label; PluginIdentifier::parseIdentifier (identifier, type, soName, label); if (pname == "") { pname = strtoqstr(plugin->getDistinctiveConfigurationText()); } if (pname != "") { pname = TQString("%1: %2").arg(label).arg(pname); } else { pname = label; } } else { connected = false; } } } else if ((*it)->getType() == Instrument::Audio) { connected = true; } else { connected = (device->getConnection() != ""); } bool instrUsedByMe = false; bool instrUsedByAnyone = false; if (thisTrackInstr && thisTrackInstr->getId() == (*it)->getId()) { instrUsedByMe = true; instrUsedByAnyone = true; } if (devId != (DeviceId)(currentDevId)) { 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; } } } TQIconSet iconSet (connected ? (deviceUsedByAnyone ? connectedUsedPixmap : connectedPixmap) : (deviceUsedByAnyone ? unconnectedUsedPixmap : unconnectedPixmap)); currentDevId = int(devId); TQPopupMenu *subMenu = new TQPopupMenu(instrumentPopup); TQString deviceName = strtoqstr(device->getName()); instrumentPopup->insertItem(iconSet, deviceName, subMenu); instrumentSubMenus.push_back(subMenu); // Connect up the submenu // connect(subMenu, TQT_SIGNAL(activated(int)), TQT_SLOT(slotInstrumentPopupActivated(int))); } else if (!instrUsedByMe) { for (Composition::trackcontainer::iterator tit = comp.getTracks().begin(); tit != comp.getTracks().end(); ++tit) { if (tit->second->getInstrument() == (*it)->getId()) { instrUsedByAnyone = true; break; } } } TQIconSet iconSet (connected ? (instrUsedByAnyone ? instrUsedByMe ? connectedSelectedPixmap : connectedUsedPixmap : connectedPixmap) : (instrUsedByAnyone ? instrUsedByMe ? unconnectedSelectedPixmap : unconnectedUsedPixmap : unconnectedPixmap)); if (pname != "") iname += " (" + pname + ")"; instrumentSubMenus[instrumentSubMenus.size() - 1]->insertItem(iconSet, iname, i++); } } void TrackButtons::slotInstrumentPopupActivated(int item) { RG_DEBUG << "TrackButtons::slotInstrumentPopupActivated " << item << endl; Composition &comp = m_doc->getComposition(); Studio &studio = m_doc->getStudio(); Instrument *inst = studio.getInstrumentFromList(item); RG_DEBUG << "TrackButtons::slotInstrumentPopupActivated: instrument " << inst << endl; if (inst != 0) { Track *track = comp.getTrackByPosition(m_popupItem); if (track != 0) { track->setInstrument(inst->getId()); // select instrument emit instrumentSelected((int)inst->getId()); m_trackLabels[m_popupItem]->getInstrumentLabel()-> setText(strtoqstr(inst->getPresentationName())); // reset the alternative label m_trackLabels[m_popupItem]->clearAlternativeLabel(); // Now see if the program is being shown for this instrument // and if so reset the label // if (inst->sendsProgramChange()) m_trackLabels[m_popupItem]->setAlternativeLabel(strtoqstr(inst->getProgramName())); if (inst->getType() == Instrument::Audio) { m_recordLeds[m_popupItem]->setColor (GUIPalette::getColour (GUIPalette::RecordAudioTrackLED)); } else { m_recordLeds[m_popupItem]->setColor (GUIPalette::getColour (GUIPalette::RecordMIDITrackLED)); } } else RG_DEBUG << "slotInstrumentPopupActivated() - can't find item!\n"; } else RG_DEBUG << "slotInstrumentPopupActivated() - can't find item!\n"; } void TrackButtons::changeTrackInstrumentLabels(TrackLabel::InstrumentTrackLabels label) { // Set new label m_trackInstrumentLabels = label; // update and reconnect with new value for (int i = 0; i < (int)m_tracks; i++) { m_trackLabels[i]->showLabel(label); } } void TrackButtons::changeInstrumentLabel(InstrumentId id, TQString label) { Composition &comp = m_doc->getComposition(); Track *track; for (int i = 0; i < (int)m_tracks; i++) { track = comp.getTrackByPosition(i); if (track && track->getInstrument() == id) { m_trackLabels[i]->setAlternativeLabel(label); Instrument *ins = m_doc->getStudio(). getInstrumentById(track->getInstrument()); if (ins && ins->getType() == Instrument::Audio) { m_recordLeds[i]->setColor (GUIPalette::getColour (GUIPalette::RecordAudioTrackLED)); } else { m_recordLeds[i]->setColor (GUIPalette::getColour (GUIPalette::RecordMIDITrackLED)); } } } } void TrackButtons::changeTrackLabel(TrackId id, TQString label) { Composition &comp = m_doc->getComposition(); Track *track; for (int i = 0; i < (int)m_tracks; i++) { track = comp.getTrackByPosition(i); if (track && track->getId() == id) { if (m_trackLabels[i]->getTrackLabel()->text() != label) { m_trackLabels[i]->getTrackLabel()->setText(label); emit widthChanged(); emit nameChanged(); } return ; } } } void TrackButtons::slotSynchroniseWithComposition() { Composition &comp = m_doc->getComposition(); Studio &studio = m_doc->getStudio(); Track *track; for (int i = 0; i < (int)m_tracks; i++) { track = comp.getTrackByPosition(i); if (track) { if (track->isMuted()) m_muteLeds[i]->off(); else m_muteLeds[i]->on(); Instrument *ins = studio. getInstrumentById(track->getInstrument()); TQString instrumentName(i18n("")); if (ins) instrumentName = strtoqstr(ins->getPresentationName()); m_trackLabels[i]->getInstrumentLabel()->setText(instrumentName); setRecordButton(i, comp.isTrackRecording(track->getId())); if (ins && ins->getType() == Instrument::Audio) { m_recordLeds[i]->setColor (GUIPalette::getColour (GUIPalette::RecordAudioTrackLED)); } else { m_recordLeds[i]->setColor (GUIPalette::getColour (GUIPalette::RecordMIDITrackLED)); } } } } void TrackButtons::slotLabelSelected(int position) { Track *track = m_doc->getComposition().getTrackByPosition(position); if (track) { emit trackSelected(track->getId()); } } void TrackButtons::setMuteButton(TrackId track, bool value) { Track *trackObj = m_doc->getComposition().getTrackById(track); if (trackObj == 0) return ; int pos = trackObj->getPosition(); RG_DEBUG << "TrackButtons::setMuteButton() trackId = " << track << ", pos = " << pos << endl; m_muteLeds[pos]->setState(value ? KLed::Off : KLed::On); } void TrackButtons::slotTrackInstrumentSelection(TrackId trackId, int item) { RG_DEBUG << "TrackButtons::slotTrackInstrumentSelection(" << trackId << ")\n"; Composition &comp = m_doc->getComposition(); int position = comp.getTrackById(trackId)->getPosition(); m_popupItem = position; slotInstrumentPopupActivated( item ); } TQFrame* TrackButtons::makeButton(Rosegarden::TrackId trackId) { // The buttonGap sets up the sizes of the buttons // static const int buttonGap = 8; TQFrame *trackHBox = 0; KLedButton *mute = 0; KLedButton *record = 0; TrackVUMeter *vuMeter = 0; TrackLabel *trackLabel = 0; int vuWidth = 20; int vuSpacing = 2; int multiple = m_doc->getComposition() .getMaxContemporaneousSegmentsOnTrack(trackId); if (multiple == 0) multiple = 1; int labelWidth = m_trackLabelWidth - ( (m_cellSize - buttonGap) * 2 + vuSpacing * 2 + vuWidth ); // Set the label from the Track object on the Composition // Rosegarden::Track *track = m_doc->getComposition().getTrackById(trackId); if (track == 0) return 0; // Create a horizontal box for each track // trackHBox = new TQFrame(this); TQHBoxLayout *hblayout = new TQHBoxLayout(trackHBox); trackHBox->setMinimumSize(labelWidth, m_cellSize * multiple - m_borderGap); trackHBox->setFixedHeight(m_cellSize * multiple - m_borderGap); // Try a style for the box // trackHBox->setFrameStyle(StyledPanel); trackHBox->setFrameShape(StyledPanel); trackHBox->setFrameShadow(Raised); // Insert a little gap hblayout->addSpacing(vuSpacing); // Create a VU meter vuMeter = new TrackVUMeter(trackHBox, VUMeter::PeakHold, vuWidth, buttonGap, track->getPosition()); m_trackMeters.push_back(vuMeter); hblayout->addWidget(vuMeter); // Create another little gap hblayout->addSpacing(vuSpacing); // // 'mute' and 'record' leds // mute = new KLedButton(Rosegarden::GUIPalette::getColour (Rosegarden::GUIPalette::MuteTrackLED), trackHBox); TQToolTip::add(mute, i18n("Mute track")); hblayout->addWidget(mute); record = new KLedButton(Rosegarden::GUIPalette::getColour (Rosegarden::GUIPalette::RecordMIDITrackLED), trackHBox); TQToolTip::add(record, i18n("Record on this track")); hblayout->addWidget(record); record->setLook(KLed::Sunken); mute->setLook(KLed::Sunken); record->off(); // Connect them to their sigmappers connect(record, TQT_SIGNAL(stateChanged(bool)), m_recordSigMapper, TQT_SLOT(map())); connect(mute, TQT_SIGNAL(stateChanged(bool)), m_muteSigMapper, TQT_SLOT(map())); m_recordSigMapper->setMapping(TQT_TQOBJECT(record), track->getPosition()); m_muteSigMapper->setMapping(TQT_TQOBJECT(mute), track->getPosition()); // Store the KLedButton // m_muteLeds.push_back(mute); m_recordLeds.push_back(record); // // Track label // trackLabel = new TrackLabel(trackId, track->getPosition(), trackHBox); hblayout->addWidget(trackLabel); hblayout->addSpacing(vuSpacing); if (track->getLabel() == std::string("")) { Rosegarden::Instrument *ins = m_doc->getStudio().getInstrumentById(track->getInstrument()); if (ins && ins->getType() == Rosegarden::Instrument::Audio) { trackLabel->getTrackLabel()->setText(i18n("")); } else { trackLabel->getTrackLabel()->setText(i18n("")); } } else trackLabel->getTrackLabel()->setText(strtoqstr(track->getLabel())); trackLabel->setFixedSize(labelWidth, m_cellSize - buttonGap); trackLabel->setFixedHeight(m_cellSize - buttonGap); trackLabel->setIndent(7); connect(trackLabel, TQT_SIGNAL(renameTrack(TQString, TrackId)), TQT_SLOT(slotRenameTrack(TQString, TrackId))); // Store the TrackLabel pointer // m_trackLabels.push_back(trackLabel); // Connect it setButtonMapping(TQT_TQOBJECT(trackLabel), trackId); connect(trackLabel, TQT_SIGNAL(changeToInstrumentList()), m_instListSigMapper, TQT_SLOT(map())); connect(trackLabel, TQT_SIGNAL(clicked()), m_clickedSigMapper, TQT_SLOT(map())); // // instrument label // Rosegarden::Instrument *ins = m_doc->getStudio().getInstrumentById(track->getInstrument()); TQString instrumentName(i18n("")); if (ins) instrumentName = strtoqstr(ins->getPresentationName()); // Set label to program change if it's being sent // if (ins != 0 && ins->sendsProgramChange()) trackLabel->setAlternativeLabel(strtoqstr(ins->getProgramName())); trackLabel->showLabel(m_trackInstrumentLabels); mute->setFixedSize(m_cellSize - buttonGap, m_cellSize - buttonGap); record->setFixedSize(m_cellSize - buttonGap, m_cellSize - buttonGap); // set the mute button // if (track->isMuted()) mute->off(); return trackHBox; } } #include "TrackButtons.moc"