Merge branch 'stable-1.1'
Conflicts: include/AutomatableModel.h include/FxMixer.h src/core/FxMixer.cpp src/gui/widgets/caption_menu.cpp src/tracks/InstrumentTrack.cpp
This commit is contained in:
@@ -83,13 +83,11 @@ QMenu::item:selected {
|
||||
color: white;
|
||||
font-weight:bold;
|
||||
background-color: #747474;
|
||||
margin:3px;
|
||||
}
|
||||
|
||||
QMenu::item:disabled {
|
||||
color: #747474;
|
||||
background-color: #c9c9c9;
|
||||
margin:0px;
|
||||
font-size:12px;
|
||||
font-weight: normal;
|
||||
padding: 4px 32px 4px 20px;
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#ifndef AUTOMATABLE_MODEL_H
|
||||
#define AUTOMATABLE_MODEL_H
|
||||
|
||||
#include <math.h>
|
||||
#include "lmms_math.h"
|
||||
#include <QtCore/QMutex>
|
||||
|
||||
#include "JournallingObject.h"
|
||||
@@ -72,7 +72,8 @@ public:
|
||||
enum ScaleType
|
||||
{
|
||||
Linear,
|
||||
Logarithmic
|
||||
Logarithmic,
|
||||
Decibel
|
||||
};
|
||||
|
||||
enum DataType
|
||||
@@ -249,6 +250,19 @@ public:
|
||||
return m_hasLinkedModels;
|
||||
}
|
||||
|
||||
// a way to track changed values in the model and avoid using signals/slots - useful for speed-critical code.
|
||||
// note that this method should only be called once per period since it resets the state of the variable - so if your model
|
||||
// has to be accessed by more than one object, then this function shouldn't be used.
|
||||
bool isValueChanged()
|
||||
{
|
||||
if( m_valueChanged )
|
||||
{
|
||||
m_valueChanged = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
float globalAutomationValueAt( const MidiTime& time );
|
||||
|
||||
bool hasStrictStepSize() const
|
||||
@@ -318,6 +332,8 @@ private:
|
||||
float m_step;
|
||||
float m_range;
|
||||
float m_centerValue;
|
||||
|
||||
bool m_valueChanged;
|
||||
|
||||
// currently unused?
|
||||
float m_oldValue;
|
||||
|
||||
@@ -59,6 +59,7 @@ class FxChannel : public ThreadableJob
|
||||
QMutex m_lock;
|
||||
int m_channelIndex; // what channel index are we
|
||||
bool m_queued; // are we queued up for rendering yet?
|
||||
bool m_muted; // are we muted? updated per period so we don't have to call m_muteModel.value() twice
|
||||
|
||||
// pointers to other channels that this one sends to
|
||||
FxRouteVector m_sends;
|
||||
@@ -69,6 +70,11 @@ class FxChannel : public ThreadableJob
|
||||
virtual bool requiresProcessing() const { return true; }
|
||||
void unmuteForSolo();
|
||||
|
||||
|
||||
QAtomicInt m_dependenciesMet;
|
||||
void incrementDeps();
|
||||
void processed();
|
||||
|
||||
private:
|
||||
virtual void doProcessing( sampleFrame * _working_buffer );
|
||||
};
|
||||
@@ -196,10 +202,13 @@ private:
|
||||
void allocateChannelsTo(int num);
|
||||
QMutex m_sendsMutex;
|
||||
|
||||
<<<<<<< HEAD
|
||||
void addChannelLeaf( FxChannel * ch, sampleFrame * buf );
|
||||
|
||||
int m_lastSoloed;
|
||||
|
||||
=======
|
||||
>>>>>>> stable-1.1
|
||||
friend class MixerWorkerThread;
|
||||
friend class FxMixerView;
|
||||
|
||||
|
||||
@@ -61,6 +61,11 @@ public:
|
||||
{
|
||||
m_state = Queued;
|
||||
}
|
||||
|
||||
inline void done()
|
||||
{
|
||||
m_state = Done;
|
||||
}
|
||||
|
||||
void process( sampleFrame* workingBuffer = NULL )
|
||||
{
|
||||
|
||||
@@ -38,6 +38,12 @@ public:
|
||||
captionMenu( const QString & _title, QWidget * _parent = 0 );
|
||||
virtual ~captionMenu();
|
||||
|
||||
///
|
||||
/// \brief Adds a "Help" action displaying the Menu's parent's WhatsThis
|
||||
/// text when selected.
|
||||
///
|
||||
void addHelpAction();
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
@@ -52,6 +52,9 @@ BassBoosterEffect::BassBoosterEffect( Model* parent, const Descriptor::SubPlugin
|
||||
m_bbFX( DspEffectLibrary::FastBassBoost( 70.0f, 1.0f, 2.8f ) ),
|
||||
m_bbControls( this )
|
||||
{
|
||||
changeFrequency();
|
||||
changeGain();
|
||||
changeRatio();
|
||||
}
|
||||
|
||||
|
||||
@@ -70,6 +73,10 @@ bool BassBoosterEffect::processAudioBuffer( sampleFrame* buf, const fpp_t frames
|
||||
{
|
||||
return( false );
|
||||
}
|
||||
// check out changed controls
|
||||
if( m_bbControls.m_freqModel.isValueChanged() ) { changeFrequency(); }
|
||||
if( m_bbControls.m_gainModel.isValueChanged() ) { changeGain(); }
|
||||
if( m_bbControls.m_ratioModel.isValueChanged() ) { changeRatio(); }
|
||||
|
||||
double outSum = 0.0;
|
||||
const float d = dryLevel();
|
||||
@@ -91,6 +98,32 @@ bool BassBoosterEffect::processAudioBuffer( sampleFrame* buf, const fpp_t frames
|
||||
}
|
||||
|
||||
|
||||
inline void BassBoosterEffect::changeFrequency()
|
||||
{
|
||||
const sample_t fac = engine::mixer()->processingSampleRate() / 44100.0f;
|
||||
|
||||
m_bbFX.leftFX().setFrequency( m_bbControls.m_freqModel.value() * fac );
|
||||
m_bbFX.rightFX().setFrequency( m_bbControls.m_freqModel.value() * fac );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
inline void BassBoosterEffect::changeGain()
|
||||
{
|
||||
m_bbFX.leftFX().setGain( m_bbControls.m_gainModel.value() );
|
||||
m_bbFX.rightFX().setGain( m_bbControls.m_gainModel.value() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
inline void BassBoosterEffect::changeRatio()
|
||||
{
|
||||
m_bbFX.leftFX().setRatio( m_bbControls.m_ratioModel.value() );
|
||||
m_bbFX.rightFX().setRatio( m_bbControls.m_ratioModel.value() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _BASS_BOOSTER_H
|
||||
#define _BASS_BOOSTER_H
|
||||
#ifndef BASS_BOOSTER_H
|
||||
#define BASS_BOOSTER_H
|
||||
|
||||
#include "Effect.h"
|
||||
#include "DspEffectLibrary.h"
|
||||
@@ -45,6 +45,10 @@ public:
|
||||
|
||||
|
||||
private:
|
||||
void changeFrequency();
|
||||
void changeGain();
|
||||
void changeRatio();
|
||||
|
||||
DspEffectLibrary::MonoToStereoAdaptor<DspEffectLibrary::FastBassBoost> m_bbFX;
|
||||
|
||||
BassBoosterControls m_bbControls;
|
||||
|
||||
@@ -37,48 +37,17 @@ BassBoosterControls::BassBoosterControls( BassBoosterEffect* effect ) :
|
||||
m_gainModel( 1.0f, 0.1f, 5.0f, 0.05f, this, tr( "Gain" ) ),
|
||||
m_ratioModel( 2.0f, 0.1f, 10.0f, 0.1f, this, tr( "Ratio" ) )
|
||||
{
|
||||
connect( &m_freqModel, SIGNAL( dataChanged() ), this, SLOT( changeFrequency() ) );
|
||||
connect( &m_gainModel, SIGNAL( dataChanged() ), this, SLOT( changeGain() ) );
|
||||
connect( &m_ratioModel, SIGNAL( dataChanged() ), this, SLOT( changeRatio() ) );
|
||||
connect( engine::mixer(), SIGNAL( sampleRateChanged() ), this, SLOT( changeFrequency() ) );
|
||||
|
||||
changeFrequency();
|
||||
changeGain();
|
||||
changeRatio();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void BassBoosterControls::changeFrequency()
|
||||
{
|
||||
const sample_t fac = engine::mixer()->processingSampleRate() / 44100.0f;
|
||||
|
||||
m_effect->m_bbFX.leftFX().setFrequency( m_freqModel.value() * fac );
|
||||
m_effect->m_bbFX.rightFX().setFrequency( m_freqModel.value() * fac );
|
||||
m_effect->changeFrequency();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void BassBoosterControls::changeGain()
|
||||
{
|
||||
m_effect->m_bbFX.leftFX().setGain( m_gainModel.value() );
|
||||
m_effect->m_bbFX.rightFX().setGain( m_gainModel.value() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void BassBoosterControls::changeRatio()
|
||||
{
|
||||
m_effect->m_bbFX.leftFX().setRatio( m_ratioModel.value() );
|
||||
m_effect->m_bbFX.rightFX().setRatio( m_ratioModel.value() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void BassBoosterControls::loadSettings( const QDomElement& _this )
|
||||
{
|
||||
m_freqModel.loadSettings( _this, "freq" );
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _BASSBOOSTER_CONTROLS_H
|
||||
#define _BASSBOOSTER_CONTROLS_H
|
||||
#ifndef BASSBOOSTER_CONTROLS_H
|
||||
#define BASSBOOSTER_CONTROLS_H
|
||||
|
||||
#include "EffectControls.h"
|
||||
#include "BassBoosterControlDialog.h"
|
||||
@@ -62,9 +62,6 @@ public:
|
||||
|
||||
private slots:
|
||||
void changeFrequency();
|
||||
void changeGain();
|
||||
void changeRatio();
|
||||
|
||||
|
||||
private:
|
||||
BassBoosterEffect* m_effect;
|
||||
@@ -73,7 +70,7 @@ private:
|
||||
FloatModel m_ratioModel;
|
||||
|
||||
friend class BassBoosterControlDialog;
|
||||
|
||||
friend class BassBoosterEffect;
|
||||
} ;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -251,9 +251,8 @@ void nineButtonSelector::updateButton( int _new_button )
|
||||
|
||||
void nineButtonSelector::contextMenuEvent( QContextMenuEvent * )
|
||||
{
|
||||
captionMenu contextMenu( windowTitle() );
|
||||
contextMenu.addAction( embed::getIconPixmap( "help" ), tr( "&Help" ),
|
||||
this, SLOT( displayHelp() ) );
|
||||
captionMenu contextMenu( windowTitle(), this );
|
||||
contextMenu.addHelpAction();
|
||||
contextMenu.exec( QCursor::pos() );
|
||||
}
|
||||
|
||||
|
||||
@@ -756,9 +756,8 @@ void vibedView::normalizeClicked()
|
||||
void vibedView::contextMenuEvent( QContextMenuEvent * )
|
||||
{
|
||||
|
||||
captionMenu contextMenu( model()->displayName() );
|
||||
contextMenu.addAction( embed::getIconPixmap( "help" ), tr( "&Help" ),
|
||||
this, SLOT( displayHelp() ) );
|
||||
captionMenu contextMenu( model()->displayName(), this );
|
||||
contextMenu.addHelpAction();
|
||||
contextMenu.exec( QCursor::pos() );
|
||||
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ AutomatableModel::AutomatableModel( DataType type,
|
||||
m_step( step ),
|
||||
m_range( max - min ),
|
||||
m_centerValue( m_minValue ),
|
||||
m_valueChanged( false ),
|
||||
m_setValueDepth( 0 ),
|
||||
m_hasStrictStepSize( false ),
|
||||
m_hasLinkedModels( false ),
|
||||
@@ -240,6 +241,7 @@ void AutomatableModel::setValue( const float value )
|
||||
(*it)->setJournalling( journalling );
|
||||
}
|
||||
}
|
||||
m_valueChanged = true;
|
||||
emit dataChanged();
|
||||
}
|
||||
else
|
||||
@@ -334,6 +336,7 @@ void AutomatableModel::setAutomatedValue( const float value )
|
||||
(*it)->setAutomatedValue( value );
|
||||
}
|
||||
}
|
||||
m_valueChanged = true;
|
||||
emit dataChanged();
|
||||
}
|
||||
--m_setValueDepth;
|
||||
@@ -478,6 +481,7 @@ void AutomatableModel::setControllerConnection( ControllerConnection* c )
|
||||
{
|
||||
QObject::connect( m_controllerConnection, SIGNAL( valueChanged() ), this, SIGNAL( dataChanged() ) );
|
||||
QObject::connect( m_controllerConnection, SIGNAL( destroyed() ), this, SLOT( unlinkControllerConnection() ) );
|
||||
m_valueChanged = true;
|
||||
emit dataChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,7 +70,8 @@ FxChannel::FxChannel( int idx, Model * _parent ) :
|
||||
m_name(),
|
||||
m_lock(),
|
||||
m_channelIndex( idx ),
|
||||
m_queued( false )
|
||||
m_queued( false ),
|
||||
m_dependenciesMet( 0 )
|
||||
{
|
||||
engine::mixer()->clearAudioBuffer( m_buffer,
|
||||
engine::mixer()->framesPerPeriod() );
|
||||
@@ -85,6 +86,27 @@ FxChannel::~FxChannel()
|
||||
}
|
||||
|
||||
|
||||
inline void FxChannel::processed()
|
||||
{
|
||||
foreach( FxRoute * receiverRoute, m_sends )
|
||||
{
|
||||
if( receiverRoute->receiver()->m_muted == false )
|
||||
{
|
||||
receiverRoute->receiver()->incrementDeps();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FxChannel::incrementDeps()
|
||||
{
|
||||
m_dependenciesMet.ref();
|
||||
if( m_dependenciesMet >= m_receives.size() )
|
||||
{
|
||||
m_queued = true;
|
||||
MixerWorkerThread::addJob( this );
|
||||
m_dependenciesMet = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void FxChannel::unmuteForSolo()
|
||||
{
|
||||
@@ -107,25 +129,14 @@ void FxChannel::doProcessing( sampleFrame * _buf )
|
||||
// <tobydox> this improves cache hit rate
|
||||
_buf = m_buffer;
|
||||
|
||||
if( m_muteModel.value() == false )
|
||||
if( m_muted == false )
|
||||
{
|
||||
// OK, we are not muted, so we go recursively through all the channels
|
||||
// which send to us (our children)...
|
||||
foreach( FxRoute * senderRoute, m_receives )
|
||||
{
|
||||
FxChannel * sender = senderRoute->sender();
|
||||
FloatModel * sendModel = senderRoute->amount();
|
||||
if( ! sendModel ) qFatal( "Error: no send model found from %d to %d", senderRoute->senderIndex(), m_channelIndex );
|
||||
|
||||
// wait for the sender job - either it's just been queued yet,
|
||||
// then ThreadableJob::process() will process it now within this
|
||||
// thread - otherwise it has been is is being processed by another
|
||||
// thread and we just have to wait for it to finish
|
||||
while( sender->state() != ThreadableJob::Done )
|
||||
{
|
||||
sender->process();
|
||||
}
|
||||
|
||||
if( sender->m_hasInput || sender->m_stillRunning )
|
||||
{
|
||||
// figure out if we're getting sample-exact input
|
||||
@@ -158,20 +169,28 @@ void FxChannel::doProcessing( sampleFrame * _buf )
|
||||
m_hasInput = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const float v = m_volumeModel.value();
|
||||
|
||||
if( m_hasInput )
|
||||
{
|
||||
// only start fxchain when we have input...
|
||||
m_fxChain.startRunning();
|
||||
}
|
||||
|
||||
m_stillRunning = m_fxChain.processAudioBuffer( _buf, fpp, m_hasInput );
|
||||
|
||||
m_peakLeft = qMax( m_peakLeft, engine::mixer()->peakValueLeft( _buf, fpp ) * v );
|
||||
m_peakRight = qMax( m_peakRight, engine::mixer()->peakValueRight( _buf, fpp ) * v );
|
||||
}
|
||||
|
||||
const float v = m_volumeModel.value();
|
||||
|
||||
if( m_hasInput )
|
||||
else
|
||||
{
|
||||
// only start fxchain when we have input...
|
||||
m_fxChain.startRunning();
|
||||
m_peakLeft = m_peakRight = 0.0f;
|
||||
}
|
||||
|
||||
m_stillRunning = m_fxChain.processAudioBuffer( _buf, fpp, m_hasInput );
|
||||
|
||||
m_peakLeft = qMax( m_peakLeft, engine::mixer()->peakValueLeft( _buf, fpp ) * v );
|
||||
m_peakRight = qMax( m_peakRight, engine::mixer()->peakValueRight( _buf, fpp ) * v );
|
||||
// increment dependency counter of all receivers
|
||||
processed();
|
||||
}
|
||||
|
||||
|
||||
@@ -456,11 +475,9 @@ void FxMixer::deleteChannelSend( FxRoute * route )
|
||||
bool FxMixer::isInfiniteLoop( fx_ch_t sendFrom, fx_ch_t sendTo )
|
||||
{
|
||||
if( sendFrom == sendTo ) return true;
|
||||
//m_sendsMutex.lock();
|
||||
FxChannel * from = m_fxChannels[sendFrom];
|
||||
FxChannel * to = m_fxChannels[sendTo];
|
||||
bool b = checkInfiniteLoop( from, to );
|
||||
//m_sendsMutex.unlock();
|
||||
return b;
|
||||
}
|
||||
|
||||
@@ -538,42 +555,38 @@ void FxMixer::prepareMasterMix()
|
||||
|
||||
|
||||
|
||||
void FxMixer::addChannelLeaf( FxChannel * ch, sampleFrame * buf )
|
||||
{
|
||||
// if we're muted or this channel is seen already, discount it
|
||||
if( ch->m_queued )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach( FxRoute * senderRoute, ch->m_receives )
|
||||
{
|
||||
addChannelLeaf( senderRoute->sender(), buf );
|
||||
}
|
||||
|
||||
// add this channel to job list
|
||||
ch->m_queued = true;
|
||||
MixerWorkerThread::addJob( ch );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void FxMixer::masterMix( sampleFrame * _buf )
|
||||
{
|
||||
const int fpp = engine::mixer()->framesPerPeriod();
|
||||
|
||||
// recursively loop through channel dependency chain
|
||||
// and add all channels to job list that have no dependencies
|
||||
// when the channel completes it will check its parent to see if it needs
|
||||
// to be processed.
|
||||
//m_sendsMutex.lock();
|
||||
MixerWorkerThread::resetJobQueue( MixerWorkerThread::JobQueue::Dynamic );
|
||||
addChannelLeaf( m_fxChannels[0], _buf );
|
||||
while( m_fxChannels[0]->state() != ThreadableJob::Done )
|
||||
if( m_sendsMutex.tryLock() )
|
||||
{
|
||||
MixerWorkerThread::startAndWaitForJobs();
|
||||
// add the channels that have no dependencies (no incoming senders, ie. no receives)
|
||||
// to the jobqueue. The channels that have receives get added when their senders get processed, which
|
||||
// is detected by dependency counting.
|
||||
// also instantly add all muted channels as they don't need to care about their senders, and can just increment the deps of
|
||||
// their recipients right away.
|
||||
MixerWorkerThread::resetJobQueue( MixerWorkerThread::JobQueue::Dynamic );
|
||||
foreach( FxChannel * ch, m_fxChannels )
|
||||
{
|
||||
ch->m_muted = ch->m_muteModel.value();
|
||||
if( ch->m_muted ) // instantly "process" muted channels
|
||||
{
|
||||
ch->processed();
|
||||
ch->done();
|
||||
}
|
||||
else if( ch->m_receives.size() == 0 )
|
||||
{
|
||||
ch->m_queued = true;
|
||||
MixerWorkerThread::addJob( ch );
|
||||
}
|
||||
}
|
||||
while( m_fxChannels[0]->state() != ThreadableJob::Done )
|
||||
{
|
||||
MixerWorkerThread::startAndWaitForJobs();
|
||||
}
|
||||
m_sendsMutex.unlock();
|
||||
}
|
||||
//m_sendsMutex.unlock();
|
||||
|
||||
// handle sample-exact data in master volume fader
|
||||
ValueBuffer * volBuf = m_fxChannels[0]->m_volumeModel.valueBuffer();
|
||||
|
||||
@@ -1044,7 +1044,7 @@ void trackContentWidget::updateBackground()
|
||||
// draw lines
|
||||
pmp.setPen( QPen( QColor( 0, 0, 0, 160 ), 1 ) );
|
||||
// horizontal line
|
||||
pmp.drawLine( 0, 0, w*2, 0 );
|
||||
pmp.drawLine( 0, h-1, w*2, h-1 );
|
||||
|
||||
// vertical lines
|
||||
for( float x = 0; x < w * 2; x += ppt )
|
||||
|
||||
@@ -176,14 +176,12 @@ void ControllerView::modelChanged()
|
||||
|
||||
void ControllerView::contextMenuEvent( QContextMenuEvent * )
|
||||
{
|
||||
QPointer<captionMenu> contextMenu = new captionMenu( model()->displayName() );
|
||||
QPointer<captionMenu> contextMenu = new captionMenu( model()->displayName(), this );
|
||||
contextMenu->addAction( embed::getIconPixmap( "cancel" ),
|
||||
tr( "&Remove this plugin" ),
|
||||
this, SLOT( deleteController() ) );
|
||||
contextMenu->addSeparator();
|
||||
contextMenu->addAction( embed::getIconPixmap( "help" ),
|
||||
tr( "&Help" ),
|
||||
this, SLOT( displayHelp() ) );
|
||||
contextMenu->addHelpAction();
|
||||
contextMenu->exec( QCursor::pos() );
|
||||
delete contextMenu;
|
||||
}
|
||||
|
||||
@@ -245,7 +245,7 @@ void EffectView::closeEffects()
|
||||
|
||||
void EffectView::contextMenuEvent( QContextMenuEvent * )
|
||||
{
|
||||
QPointer<captionMenu> contextMenu = new captionMenu( model()->displayName() );
|
||||
QPointer<captionMenu> contextMenu = new captionMenu( model()->displayName(), this );
|
||||
contextMenu->addAction( embed::getIconPixmap( "arp_up" ),
|
||||
tr( "Move &up" ),
|
||||
this, SLOT( moveUp() ) );
|
||||
@@ -257,9 +257,7 @@ void EffectView::contextMenuEvent( QContextMenuEvent * )
|
||||
tr( "&Remove this plugin" ),
|
||||
this, SLOT( deletePlugin() ) );
|
||||
contextMenu->addSeparator();
|
||||
contextMenu->addAction( embed::getIconPixmap( "help" ),
|
||||
tr( "&Help" ),
|
||||
this, SLOT( displayHelp() ) );
|
||||
contextMenu->addHelpAction();
|
||||
contextMenu->exec( QCursor::pos() );
|
||||
delete contextMenu;
|
||||
}
|
||||
|
||||
@@ -183,7 +183,7 @@ void FxLine::mouseDoubleClickEvent( QMouseEvent * )
|
||||
void FxLine::contextMenuEvent( QContextMenuEvent * )
|
||||
{
|
||||
FxMixer * mix = engine::fxMixer();
|
||||
QPointer<captionMenu> contextMenu = new captionMenu( mix->effectChannel( m_channelIndex )->m_name );
|
||||
QPointer<captionMenu> contextMenu = new captionMenu( mix->effectChannel( m_channelIndex )->m_name, this );
|
||||
if( m_channelIndex != 0 ) // no move-options in master
|
||||
{
|
||||
contextMenu->addAction( tr( "Move &left" ), this, SLOT( moveChannelLeft() ) );
|
||||
@@ -199,9 +199,7 @@ void FxLine::contextMenuEvent( QContextMenuEvent * )
|
||||
contextMenu->addSeparator();
|
||||
}
|
||||
|
||||
contextMenu->addAction( embed::getIconPixmap( "help" ),
|
||||
tr( "&Help" ),
|
||||
this, SLOT( displayHelp() ) );
|
||||
contextMenu->addHelpAction();
|
||||
contextMenu->exec( QCursor::pos() );
|
||||
delete contextMenu;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
|
||||
#include "caption_menu.h"
|
||||
#include "embed.h"
|
||||
|
||||
|
||||
|
||||
@@ -45,6 +46,19 @@ captionMenu::~captionMenu()
|
||||
|
||||
|
||||
|
||||
void captionMenu::addHelpAction()
|
||||
{
|
||||
QWidget* parent = (QWidget*) this->parent();
|
||||
|
||||
if (parent == NULL)
|
||||
return;
|
||||
|
||||
|
||||
if (! parent->whatsThis().isEmpty()) {
|
||||
addAction( embed::getIconPixmap( "help" ), tr( "&Help" ),
|
||||
parent, SLOT( displayHelp() ) );
|
||||
}
|
||||
else {
|
||||
QAction* helpAction = addAction( embed::getIconPixmap("help"), tr("Help (not available)") );
|
||||
helpAction->setDisabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -481,11 +481,10 @@ void knob::contextMenuEvent( QContextMenuEvent * )
|
||||
// an QApplication::restoreOverrideCursor()-call...
|
||||
mouseReleaseEvent( NULL );
|
||||
|
||||
captionMenu contextMenu( model()->displayName() );
|
||||
captionMenu contextMenu( model()->displayName(), this );
|
||||
addDefaultActions( &contextMenu );
|
||||
contextMenu.addSeparator();
|
||||
contextMenu.addAction( embed::getIconPixmap( "help" ), tr( "&Help" ),
|
||||
this, SLOT( displayHelp() ) );
|
||||
contextMenu.addHelpAction();
|
||||
contextMenu.exec( QCursor::pos() );
|
||||
}
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ void TempoSyncKnob::contextMenuEvent( QContextMenuEvent * )
|
||||
{
|
||||
mouseReleaseEvent( NULL );
|
||||
|
||||
captionMenu contextMenu( model()->displayName() );
|
||||
captionMenu contextMenu( model()->displayName(), this );
|
||||
addDefaultActions( &contextMenu );
|
||||
contextMenu.addSeparator();
|
||||
|
||||
@@ -147,9 +147,7 @@ void TempoSyncKnob::contextMenuEvent( QContextMenuEvent * )
|
||||
|
||||
}
|
||||
|
||||
contextMenu.addSeparator();
|
||||
contextMenu.addAction( embed::getIconPixmap( "help" ), tr( "&Help" ),
|
||||
this, SLOT( displayHelp() ) );
|
||||
contextMenu.addHelpAction();
|
||||
contextMenu.exec( QCursor::pos() );
|
||||
|
||||
delete syncMenu;
|
||||
|
||||
@@ -806,6 +806,7 @@ void InstrumentTrack::loadTrackSpecificSettings( const QDomElement & thisElement
|
||||
}
|
||||
node = node.nextSibling();
|
||||
}
|
||||
updatePitchRange();
|
||||
unlock();
|
||||
}
|
||||
|
||||
@@ -1585,10 +1586,3 @@ void InstrumentTrackWindow::loadSettings( const QDomElement& thisElement )
|
||||
m_itv->m_tlb->setChecked( true );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user