--- qsampler/trunk/src/qsamplerChannelStrip.ui.h 2005/02/17 17:27:59 388 +++ qsampler/trunk/src/qsamplerChannelStrip.ui.h 2007/01/10 19:39:00 1018 @@ -2,7 +2,7 @@ // // ui.h extension file, included from the uic-generated form implementation. /**************************************************************************** - Copyright (C) 2004-2005, rncbc aka Rui Nuno Capela. All rights reserved. + Copyright (C) 2004-2007, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -14,18 +14,20 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ #include #include +#include #include #include #include #include +#include #include @@ -34,6 +36,9 @@ #include "config.h" +// Channel status/usage usage limit control. +#define QSAMPLER_ERROR_LIMIT 3 + // Kind of constructor. void qsamplerChannelStrip::init (void) @@ -41,6 +46,7 @@ // Initialize locals. m_pChannel = NULL; m_iDirtyChange = 0; + m_iErrorCount = 0; // Try to restore normal window positioning. adjustSize(); @@ -57,6 +63,50 @@ } +// Drag'n'drop file handler. +bool qsamplerChannelStrip::decodeDragFile ( const QMimeSource *pEvent, QString& sInstrumentFile ) +{ + if (m_pChannel == NULL) + return false; + if (QTextDrag::canDecode(pEvent)) { + QString sText; + if (QTextDrag::decode(pEvent, sText)) { + QStringList files = QStringList::split('\n', sText); + for (QStringList::Iterator iter = files.begin(); iter != files.end(); iter++) { + *iter = QUrl((*iter).stripWhiteSpace().replace(QRegExp("^file:"), QString::null)).path(); + if (qsamplerChannel::isInstrumentFile(*iter)) { + sInstrumentFile = *iter; + return true; + } + } + } + } + // Fail. + return false; +} + + +// Window drag-n-drop event handlers. +void qsamplerChannelStrip::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent ) +{ + QString sInstrumentFile; + pDragEnterEvent->accept(decodeDragFile(pDragEnterEvent, sInstrumentFile)); +} + + +void qsamplerChannelStrip::dropEvent ( QDropEvent* pDropEvent ) +{ + QString sInstrumentFile; + + if (decodeDragFile(pDropEvent, sInstrumentFile)) { + // Go and set the dropped instrument filename... + m_pChannel->setInstrument(sInstrumentFile, 0); + // Open up the channel dialog. + channelSetup(); + } +} + + // Channel strip setup formal initializer. void qsamplerChannelStrip::setup ( qsamplerChannel *pChannel ) { @@ -70,6 +120,10 @@ // Stabilize this around. updateChannelInfo(); + + // We'll accept drops from now on... + if (m_pChannel) + setAcceptDrops(true); } // Channel secriptor accessor. @@ -117,89 +171,106 @@ pLabel->setPaletteBackgroundPixmap(pm); delete pList; } - + // And this standalone too. StreamVoiceCountTextLabel->setPaletteBackgroundPixmap(pm); } +// Maximum volume slider accessors. +void qsamplerChannelStrip::setMaxVolume ( int iMaxVolume ) +{ + m_iDirtyChange++; + VolumeSlider->setRange(0, iMaxVolume); + VolumeSpinBox->setRange(0, iMaxVolume); + m_iDirtyChange--; +} + + // Channel setup dialog slot. bool qsamplerChannelStrip::channelSetup (void) { - bool bResult = m_pChannel->channelSetup(this); - - if (bResult) - emit channelChanged(this); + if (m_pChannel == NULL) + return false; + + // Invoke the channel setup dialog. + bool bResult = m_pChannel->channelSetup(this); + // Notify that this channel has changed. + if (bResult) + emit channelChanged(this); - return bResult; + return bResult; } -// Update the channel instrument name. -bool qsamplerChannelStrip::updateInstrumentName ( bool bForce ) +// Channel mute slot. +bool qsamplerChannelStrip::channelMute ( bool bMute ) { if (m_pChannel == NULL) return false; - // Do we refersh the actual name? - if (bForce) - m_pChannel->updateInstrumentName(); + // Invoke the channel mute method. + bool bResult = m_pChannel->setChannelMute(bMute); + // Notify that this channel has changed. + if (bResult) + emit channelChanged(this); - // Instrument name... - if (m_pChannel->instrumentName().isEmpty()) - InstrumentNameTextLabel->setText(' ' + qsamplerChannel::noInstrumentName()); - else - InstrumentNameTextLabel->setText(' ' + m_pChannel->instrumentName()); + return bResult; +} - return true; + +// Channel solo slot. +bool qsamplerChannelStrip::channelSolo ( bool bSolo ) +{ + if (m_pChannel == NULL) + return false; + + // Invoke the channel solo method. + bool bResult = m_pChannel->setChannelSolo(bSolo); + // Notify that this channel has changed. + if (bResult) + emit channelChanged(this); + + return bResult; } -// Update whole channel info state. -bool qsamplerChannelStrip::updateChannelInfo (void) +// Channel reset slot. +bool qsamplerChannelStrip::channelReset (void) { - if (m_pChannel == NULL) - return false; - - // Update strip caption. - QString sText = m_pChannel->channelName(); - setCaption(sText); - ChannelSetupPushButton->setText(sText); + if (m_pChannel == NULL) + return false; - // Check if we're up and connected. - if (m_pChannel->client() == NULL) - return false; + // Invoke the channel reset method. + bool bResult = m_pChannel->channelReset(); + // Notify that this channel has changed. + if (bResult) + emit channelChanged(this); - // Read actual channel information. - m_pChannel->updateChannelInfo(); + return bResult; +} - // Engine name... - if (m_pChannel->engineName().isEmpty()) - EngineNameTextLabel->setText(' ' + qsamplerChannel::noEngineName()); - else - EngineNameTextLabel->setText(' ' + m_pChannel->engineName()); - // Instrument name... - updateInstrumentName(false); +// Update the channel instrument name. +bool qsamplerChannelStrip::updateInstrumentName ( bool bForce ) +{ + if (m_pChannel == NULL) + return false; - // Instrument status... - int iInstrumentStatus = m_pChannel->instrumentStatus(); - if (iInstrumentStatus < 0) { - InstrumentStatusTextLabel->setPaletteForegroundColor(Qt::red); - InstrumentStatusTextLabel->setText(tr("ERR%1").arg(iInstrumentStatus)); - } else { - InstrumentStatusTextLabel->setPaletteForegroundColor(iInstrumentStatus < 100 ? Qt::yellow : Qt::green); - InstrumentStatusTextLabel->setText(QString::number(iInstrumentStatus) + "%"); - } + // Do we refresh the actual name? + if (bForce) + m_pChannel->updateInstrumentName(); - // MIDI Port/Channel... - if (m_pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL) - MidiPortChannelTextLabel->setText(QString("%1 / *").arg(m_pChannel->midiPort())); - else - MidiPortChannelTextLabel->setText(QString("%1 / %2").arg(m_pChannel->midiPort()).arg(m_pChannel->midiChannel() + 1)); + // Instrument name... + if (m_pChannel->instrumentName().isEmpty()) { + if (m_pChannel->instrumentStatus() >= 0) + InstrumentNameTextLabel->setText(' ' + qsamplerChannel::loadingInstrument()); + else + InstrumentNameTextLabel->setText(' ' + qsamplerChannel::noInstrumentName()); + } else + InstrumentNameTextLabel->setText(' ' + m_pChannel->instrumentName()); - // And update the both GUI volume elements. - return updateChannelVolume(); + return true; } @@ -232,48 +303,111 @@ VolumeSlider->setValue(iVolume); VolumeSpinBox->setValue(iVolume); m_iDirtyChange--; - + return true; } -// Update whole channel usage state. -bool qsamplerChannelStrip::updateChannelUsage (void) +// Update whole channel info state. +bool qsamplerChannelStrip::updateChannelInfo (void) { if (m_pChannel == NULL) return false; - if (m_pChannel->client() == NULL) - return false; - // Update whole channel status info, - // if instrument load is still pending... - if (m_pChannel->instrumentStatus() < 100) { - updateChannelInfo(); - // Check (updated) status again... - if (m_pChannel->instrumentStatus() < 100) - return false; - // Once we get a complete instrument load, - // we'll try an implied channel reset... - m_pChannel->resetChannel(); + // Check for error limit/recycle... + if (m_iErrorCount > QSAMPLER_ERROR_LIMIT) + return true; + + // Update strip caption. + QString sText = m_pChannel->channelName(); + setCaption(sText); + ChannelSetupPushButton->setText(sText); + + // Check if we're up and connected. + qsamplerMainForm *pMainForm = qsamplerMainForm::getInstance(); + if (pMainForm->client() == NULL) + return false; + + // Read actual channel information. + m_pChannel->updateChannelInfo(); + + // Engine name... + if (m_pChannel->engineName().isEmpty()) + EngineNameTextLabel->setText(' ' + qsamplerChannel::noEngineName()); + else + EngineNameTextLabel->setText(' ' + m_pChannel->engineName()); + + // Instrument name... + updateInstrumentName(false); + + // MIDI Port/Channel... + QString sMidiPortChannel = QString::number(m_pChannel->midiPort()) + " / "; + if (m_pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL) + sMidiPortChannel += tr("All"); + else + sMidiPortChannel += QString::number(m_pChannel->midiChannel() + 1); + MidiPortChannelTextLabel->setText(sMidiPortChannel); + + // Instrument status... + int iInstrumentStatus = m_pChannel->instrumentStatus(); + if (iInstrumentStatus < 0) { + InstrumentStatusTextLabel->setPaletteForegroundColor(Qt::red); + InstrumentStatusTextLabel->setText(tr("ERR%1").arg(iInstrumentStatus)); + m_iErrorCount++; + return false; } - - // Check again that we're clean. - if (m_pChannel->instrumentStatus() < 100) + // All seems normal... + InstrumentStatusTextLabel->setPaletteForegroundColor(iInstrumentStatus < 100 ? Qt::yellow : Qt::green); + InstrumentStatusTextLabel->setText(QString::number(iInstrumentStatus) + '%'); + m_iErrorCount = 0; + +#ifdef CONFIG_MUTE_SOLO + // Mute/Solo button state coloring... + const QColor& rgbNormal = ChannelSetupPushButton->paletteBackgroundColor(); + bool bMute = m_pChannel->channelMute(); + ChannelMutePushButton->setPaletteBackgroundColor(bMute ? Qt::red : rgbNormal); + ChannelMutePushButton->setDown(bMute); + bool bSolo = m_pChannel->channelSolo(); + ChannelSoloPushButton->setPaletteBackgroundColor(bSolo ? Qt::yellow : rgbNormal); + ChannelSoloPushButton->setDown(bSolo); +#else + ChannelMutePushButton->setEnabled(false); + ChannelSoloPushButton->setEnabled(false); +#endif + + // And update the both GUI volume elements; + // return success if, and only if, intrument is fully loaded... + return updateChannelVolume() && (iInstrumentStatus == 100); +} + + +// Update whole channel usage state. +bool qsamplerChannelStrip::updateChannelUsage (void) +{ + if (m_pChannel == NULL) return false; + qsamplerMainForm *pMainForm = qsamplerMainForm::getInstance(); + if (pMainForm->client() == NULL) + return false; + + // This only makes sense on fully loaded channels... + if (m_pChannel->instrumentStatus() < 100) + return false; + // Get current channel voice count. - int iVoiceCount = ::lscp_get_channel_voice_count(m_pChannel->client(), m_pChannel->channelID()); + int iVoiceCount = ::lscp_get_channel_voice_count(pMainForm->client(), m_pChannel->channelID()); // Get current stream count. - int iStreamCount = ::lscp_get_channel_stream_count(m_pChannel->client(), m_pChannel->channelID()); + int iStreamCount = ::lscp_get_channel_stream_count(pMainForm->client(), m_pChannel->channelID()); // Get current channel buffer fill usage. // As benno has suggested this is the percentage usage // of the least filled buffer stream... - int iStreamUsage = ::lscp_get_channel_stream_usage(m_pChannel->client(), m_pChannel->channelID());; + int iStreamUsage = ::lscp_get_channel_stream_usage(pMainForm->client(), m_pChannel->channelID());; // Update the GUI elements... StreamUsageProgressBar->setProgress(iStreamUsage); StreamVoiceCountTextLabel->setText(QString("%1 / %2").arg(iStreamCount).arg(iVoiceCount)); - + // We're clean. return true; } @@ -307,19 +441,16 @@ { if (m_pChannel == NULL) return; - + // We'll just show up the main form's edit menu (thru qsamplerChannel). m_pChannel->contextMenuEvent(pEvent); } -// Maximum volume slider accessors. -void qsamplerChannelStrip::setMaxVolume ( int iMaxVolume ) +// Error count hackish accessors. +void qsamplerChannelStrip::resetErrorCount (void) { - m_iDirtyChange++; - VolumeSlider->setRange(0, iMaxVolume); - VolumeSpinBox->setRange(0, iMaxVolume); - m_iDirtyChange--; + m_iErrorCount = 0; }