--- qsampler/trunk/src/qsamplerChannelStrip.ui.h 2004/09/29 16:05:24 265 +++ qsampler/trunk/src/qsamplerChannelStrip.ui.h 2005/02/20 19:13:33 395 @@ -2,7 +2,7 @@ // // ui.h extension file, included from the uic-generated form implementation. /**************************************************************************** - Copyright (C) 2004, rncbc aka Rui Nuno Capela. All rights reserved. + Copyright (C) 2004-2005, 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 @@ -22,9 +22,11 @@ #include #include +#include #include #include #include +#include #include @@ -33,14 +35,18 @@ #include "config.h" +// Channel status/usage usage limit control. +#define QSAMPLER_ERROR_LIMIT 3 +#define QSAMPLER_ERROR_CYCLE 33 + // Kind of constructor. void qsamplerChannelStrip::init (void) { // Initialize locals. - m_pMainForm = NULL; m_pChannel = NULL; m_iDirtyChange = 0; + m_iErrorCount = 0; // Try to restore normal window positioning. adjustSize(); @@ -57,26 +63,68 @@ } +// 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 = (*iter).stripWhiteSpace().replace(QRegExp("^file:"), QString::null); + 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 ( qsamplerMainForm *pMainForm, int iChannelID ) +void qsamplerChannelStrip::setup ( qsamplerChannel *pChannel ) { - // Set main form reference. - m_pMainForm = pMainForm; - - // Destroy any previous channel descriptor. + // Destroy any previous channel descriptor; + // (remember that once setup we own it!) if (m_pChannel) delete m_pChannel; - // Create a new one... - m_pChannel = new qsamplerChannel(pMainForm); - // And set appropriate settings. - if (m_pChannel) { - m_pChannel->setChannelID(iChannelID); - m_iDirtyChange = 0; - } + // Set the new one... + m_pChannel = pChannel; // Stabilize this around. updateChannelInfo(); + + // We'll accept drops from now on... + if (m_pChannel) + setAcceptDrops(true); } // Channel secriptor accessor. @@ -101,61 +149,108 @@ } -// Channel setup dialog slot. -void qsamplerChannelStrip::channelSetup (void) +// Channel display background effect. +void qsamplerChannelStrip::setDisplayEffect ( bool bDisplayEffect ) { - showChannelSetup(false); + QPixmap pm; + if (bDisplayEffect) + pm = QPixmap::fromMimeSource("displaybg1.png"); + setDisplayBackground(pm); } -// Channel setup dialog. -void qsamplerChannelStrip::showChannelSetup ( bool bNew ) +// Update main display background pixmap. +void qsamplerChannelStrip::setDisplayBackground ( const QPixmap& pm ) { - qsamplerChannelForm *pChannelForm = new qsamplerChannelForm(this); - if (pChannelForm) { - pChannelForm->setup(m_pChannel, bNew); - if (pChannelForm->exec()) { - updateChannelInfo(); - emit channelChanged(this); - } - delete pChannelForm; + // Set the main origin... + ChannelInfoFrame->setPaletteBackgroundPixmap(pm); + + // Iterate for every child text label... + QObjectList *pList = ChannelInfoFrame->queryList("QLabel"); + if (pList) { + for (QLabel *pLabel = (QLabel *) pList->first(); pLabel; pLabel = (QLabel *) pList->next()) + 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) +{ + // Invoke the channel setup dialog. + bool bResult = m_pChannel->channelSetup(this); + + if (bResult) { + // Reset the error/cycle. + m_iErrorCount = 0; + // Notify that thie channel has changed. + emit channelChanged(this); + } + + return bResult; +} + + +// Update the channel instrument name. +bool qsamplerChannelStrip::updateInstrumentName ( bool bForce ) +{ + if (m_pChannel == NULL) + return false; + + // Do we refersh the actual name? + if (bForce) + m_pChannel->updateInstrumentName(); + + // Instrument name... + if (m_pChannel->instrumentName().isEmpty()) + InstrumentNameTextLabel->setText(' ' + qsamplerChannel::noInstrumentName()); + else + InstrumentNameTextLabel->setText(' ' + m_pChannel->instrumentName()); + + return true; } // Update whole channel info state. -void qsamplerChannelStrip::updateChannelInfo (void) +bool qsamplerChannelStrip::updateChannelInfo (void) { if (m_pChannel == NULL) - return; + return false; // Update strip caption. - QString sText = tr("Channel %1").arg(m_pChannel->channelID()); + QString sText = m_pChannel->channelName(); setCaption(sText); ChannelSetupPushButton->setText(sText); // Check if we're up and connected. if (m_pChannel->client() == NULL) - return; + return false; // Read actual channel information. m_pChannel->updateChannelInfo(); - // Set some proper display values. - const QString sIndent = " "; - // Engine name... if (m_pChannel->engineName().isEmpty()) - EngineNameTextLabel->setText(sIndent + tr("(No engine)")); + EngineNameTextLabel->setText(' ' + qsamplerChannel::noEngineName()); else - EngineNameTextLabel->setText(sIndent + m_pChannel->engineName()); + EngineNameTextLabel->setText(' ' + m_pChannel->engineName()); - // Instrument name... - if (m_pChannel->instrumentFile().isEmpty()) - InstrumentNameTextLabel->setText(sIndent + tr("(No instrument)")); - else - InstrumentNameTextLabel->setText(sIndent + QString("%1 [%2]") - .arg(QFileInfo(m_pChannel->instrumentFile()).fileName()).arg(m_pChannel->instrumentNr())); + // Instrument name... + updateInstrumentName(false); // Instrument status... int iInstrumentStatus = m_pChannel->instrumentStatus(); @@ -168,21 +263,21 @@ } // MIDI Port/Channel... - if (m_pChannel->midiChannel() > 0) - MidiPortChannelTextLabel->setText(QString("%1 / %2").arg(m_pChannel->midiPort()).arg(m_pChannel->midiChannel())); - else + 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)); // And update the both GUI volume elements. - updateChannelVolume(); + return updateChannelVolume(); } // Do the dirty volume change. -void qsamplerChannelStrip::updateChannelVolume (void) +bool qsamplerChannelStrip::updateChannelVolume (void) { if (m_pChannel == NULL) - return; + return false; // Convert... #ifdef CONFIG_ROUND @@ -207,28 +302,46 @@ VolumeSlider->setValue(iVolume); VolumeSpinBox->setValue(iVolume); m_iDirtyChange--; + + return true; } // Update whole channel usage state. -void qsamplerChannelStrip::updateChannelUsage (void) +bool qsamplerChannelStrip::updateChannelUsage (void) { if (m_pChannel == NULL) - return; + return false; if (m_pChannel->client() == NULL) - return; - - // Conditionally update whole channel status info. - if (m_pChannel->instrumentStatus() >= 0 && m_pChannel->instrumentStatus() < 100) { - updateChannelInfo(); - // Once we get a complete instrument load, try a implied reset channel.... - if (m_pChannel->instrumentStatus() == 100) - m_pChannel->resetChannel(); - } - // Leave, if we still have an erroneus or incomplete instrument load. - if (m_pChannel->instrumentStatus() < 100) - return; + return false; + // Check for error limit/recycle... + if (m_iErrorCount > QSAMPLER_ERROR_LIMIT) + m_iErrorCount -= QSAMPLER_ERROR_CYCLE; + if (m_iErrorCount < 0) { + m_iErrorCount++; + return false; + } + + // Update whole channel status info, + // if instrument load is still pending... + if (m_pChannel->instrumentStatus() < 100) { + // grab the whole sampler channel data... + updateChannelInfo(); + // Check (updated) status again... + int iInstrumentStatus = m_pChannel->instrumentStatus(); + if (iInstrumentStatus < 100) { + if (iInstrumentStatus < 0) + m_iErrorCount++; + return false; + } + // Once we get a complete instrument load, + // we'll try an implied channel reset... + m_pChannel->resetChannel(); + // Reset error count. + m_iErrorCount = 0; + } + // Get current channel voice count. int iVoiceCount = ::lscp_get_channel_voice_count(m_pChannel->client(), m_pChannel->channelID()); // Get current stream count. @@ -241,6 +354,9 @@ // Update the GUI elements... StreamUsageProgressBar->setProgress(iStreamUsage); StreamVoiceCountTextLabel->setText(QString("%1 / %2").arg(iStreamCount).arg(iVoiceCount)); + + // We're clean. + return true; } @@ -270,21 +386,11 @@ // Context menu event handler. void qsamplerChannelStrip::contextMenuEvent( QContextMenuEvent *pEvent ) { - if (m_pMainForm == NULL) + if (m_pChannel == NULL) return; - // We'll just show up the main form's edit menu. - m_pMainForm->contextMenuEvent(pEvent); -} - - -// Maximum volume slider accessors. -void qsamplerChannelStrip::setMaxVolume ( int iMaxVolume ) -{ - m_iDirtyChange++; - VolumeSlider->setRange(0, iMaxVolume); - VolumeSpinBox->setRange(0, iMaxVolume); - m_iDirtyChange--; + // We'll just show up the main form's edit menu (thru qsamplerChannel). + m_pChannel->contextMenuEvent(pEvent); }