You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
rosegarden/src/gui/editors/segment/TrackButtons.cpp

1148 lines
34 KiB

/*
Rosegarden
A MIDI and audio sequencer and musical notation editor.
This program is Copyright 2000-2008
Guillaume Laurent <glaurent@telegraph-road.org>,
Chris Cannam <cannam@all-day-breakfast.com>,
Richard Bown <richard.bown@ferventsoftware.com>
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 <tqlayout.h>
#include <tdelocale.h>
#include <kstddirs.h>
#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 <tdeglobal.h>
#include <kled.h>
#include <tdemessagebox.h>
#include <tqcursor.h>
#include <tqframe.h>
#include <tqiconset.h>
#include <tqlabel.h>
#include <tqobject.h>
#include <tqpixmap.h>
#include <tqpopupmenu.h>
#include <tqsignalmapper.h>
#include <tqstring.h>
#include <tqtimer.h>
#include <tqwidget.h>
#include <tqwidgetstack.h>
#include <tqtooltip.h>
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(this)),
m_muteSigMapper(new TQSignalMapper(this)),
m_clickedSigMapper(new TQSignalMapper(this)),
m_instListSigMapper(new TQSignalMapper(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, TQ_SIGNAL(mapped(int)),
this, TQ_SLOT(slotToggleRecordTrack(int)));
connect(m_muteSigMapper, TQ_SIGNAL(mapped(int)),
this, TQ_SLOT(slotToggleMutedTrack(int)));
// connect signal mappers
connect(m_instListSigMapper, TQ_SIGNAL(mapped(int)),
this, TQ_SLOT(slotInstrumentSelection(int)));
connect(m_clickedSigMapper, TQ_SIGNAL(mapped(int)),
this, TQ_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(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("<no instrument>"));
}
m_trackLabels[i]->update();
}
}
std::vector<int>
TrackButtons::mutedTracks()
{
std::vector<int> 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<TrackLabel*>::iterator tit = m_trackLabels.begin();
tit += position;
m_trackLabels.erase(tit);
std::vector<TrackVUMeter*>::iterator vit = m_trackMeters.begin();
vit += position;
m_trackMeters.erase(vit);
std::vector<KLedButton*>::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<TQFrame*>::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("<untitled audio>"));
} else {
trackLabel->setText(i18n("<untitled>"));
}
} else {
trackLabel->setText(strtoqstr(track->getLabel()));
}
// RG_DEBUG << "TrackButtons::slotUpdateTracks - set button mapping at pos "
// << i << " to track id " << track->getId() << endl;
setButtonMapping(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<int>
TrackButtons::getHighlightedTracks()
{
std::vector<int> 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("<no instrument>");
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<TQPopupMenu*> 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, TQ_SIGNAL(activated(int)),
TQ_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("<no instrument>"));
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, TQ_SIGNAL(stateChanged(bool)),
m_recordSigMapper, TQ_SLOT(map()));
connect(mute, TQ_SIGNAL(stateChanged(bool)),
m_muteSigMapper, TQ_SLOT(map()));
m_recordSigMapper->setMapping(record, track->getPosition());
m_muteSigMapper->setMapping(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("<untitled audio>"));
} else {
trackLabel->getTrackLabel()->setText(i18n("<untitled>"));
}
}
else
trackLabel->getTrackLabel()->setText(strtoqstr(track->getLabel()));
trackLabel->setFixedSize(labelWidth, m_cellSize - buttonGap);
trackLabel->setFixedHeight(m_cellSize - buttonGap);
trackLabel->setIndent(7);
connect(trackLabel, TQ_SIGNAL(renameTrack(TQString, TrackId)),
TQ_SLOT(slotRenameTrack(TQString, TrackId)));
// Store the TrackLabel pointer
//
m_trackLabels.push_back(trackLabel);
// Connect it
setButtonMapping(trackLabel, trackId);
connect(trackLabel, TQ_SIGNAL(changeToInstrumentList()),
m_instListSigMapper, TQ_SLOT(map()));
connect(trackLabel, TQ_SIGNAL(clicked()),
m_clickedSigMapper, TQ_SLOT(map()));
//
// instrument label
//
Rosegarden::Instrument *ins =
m_doc->getStudio().getInstrumentById(track->getInstrument());
TQString instrumentName(i18n("<no instrument>"));
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"