diff --git a/include/PeakController.h b/include/PeakController.h index 96240c6df..9d930446a 100644 --- a/include/PeakController.h +++ b/include/PeakController.h @@ -53,6 +53,9 @@ public: virtual void loadSettings( const QDomElement & _this ); virtual QString nodeName() const; + static void initGetControllerBySetting(); + static PeakController * getControllerBySetting( const QDomElement & _this ); + static PeakControllerEffectVector s_effects; @@ -67,6 +70,11 @@ protected: PeakControllerEffect * m_peakEffect; friend class PeakControllerDialog; + +private: + //backward compatibility for <= 0.4.15 + static int m_getCount; + static bool m_buggedFile; } ; diff --git a/plugins/peak_controller_effect/peak_controller_effect.h b/plugins/peak_controller_effect/peak_controller_effect.h index c35287f0a..acbe58e2f 100644 --- a/plugins/peak_controller_effect/peak_controller_effect.h +++ b/plugins/peak_controller_effect/peak_controller_effect.h @@ -48,6 +48,11 @@ public: return m_lastSample; } + PeakController * controller() + { + return m_autoController; + } + int m_effectId; private: @@ -57,7 +62,7 @@ private: float m_lastRMS; bool m_lastRMSavail; - Controller * m_autoController; + PeakController * m_autoController; friend class PeakControllerEffectControls; diff --git a/plugins/peak_controller_effect/peak_controller_effect_controls.cpp b/plugins/peak_controller_effect/peak_controller_effect_controls.cpp index 6104df138..b204072e2 100644 --- a/plugins/peak_controller_effect/peak_controller_effect_controls.cpp +++ b/plugins/peak_controller_effect/peak_controller_effect_controls.cpp @@ -49,6 +49,7 @@ PeakControllerEffectControls( PeakControllerEffect * _eff ) : + void PeakControllerEffectControls::loadSettings( const QDomElement & _this ) { m_baseModel.loadSettings( _this, "base" ); @@ -77,7 +78,7 @@ void PeakControllerEffectControls::loadSettings( const QDomElement & _this ) m_effect->m_effectId = rand(); } - if( m_effect->m_autoController && ( engine::getSong()->isLoadingProject() == true || PresetPreviewPlayHandle::isPreviewing() == false ) ) + if( m_effect->m_autoController && PresetPreviewPlayHandle::isPreviewing() == false ) { delete m_effect->m_autoController; m_effect->m_autoController = 0; diff --git a/src/core/Controller.cpp b/src/core/Controller.cpp index e11c2255d..4356cb9b3 100644 --- a/src/core/Controller.cpp +++ b/src/core/Controller.cpp @@ -177,12 +177,13 @@ Controller * Controller::create( ControllerTypes _ct, Model * _parent ) QString() ); break; - case Controller::LfoController: - c = new ::LfoController( _parent ); + case Controller::LfoController: + c = new ::LfoController( _parent ); break; case Controller::PeakController: - c = new ::PeakController( _parent ); + //Already instantiated in EffectChain::loadSettings() + Q_ASSERT( false ); break; case Controller::MidiController: @@ -200,9 +201,18 @@ Controller * Controller::create( ControllerTypes _ct, Model * _parent ) Controller * Controller::create( const QDomElement & _this, Model * _parent ) { - Controller * c = create( - static_cast( _this.attribute( "type" ).toInt() ), - _parent ); + Controller * c; + if( _this.attribute( "type" ).toInt() == Controller::PeakController ) + { + c = PeakController::getControllerBySetting( _this ); + } + else + { + c = create( + static_cast( _this.attribute( "type" ).toInt() ), + _parent ); + } + if( c != NULL ) { c->restoreState( _this ); diff --git a/src/core/PeakController.cpp b/src/core/PeakController.cpp index b75edbc93..1069cbda1 100644 --- a/src/core/PeakController.cpp +++ b/src/core/PeakController.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include "song.h" @@ -39,6 +40,8 @@ #include "plugins/peak_controller_effect/peak_controller_effect.h" PeakControllerEffectVector PeakController::s_effects; +int PeakController::m_getCount; +bool PeakController::m_buggedFile; PeakController::PeakController( Model * _parent, @@ -47,7 +50,7 @@ PeakController::PeakController( Model * _parent, m_peakEffect( _peak_effect ) { if( m_peakEffect ) - { + { connect( m_peakEffect, SIGNAL( destroyed( ) ), this, SLOT( handleDestroyedEffect( ) ) ); } @@ -103,6 +106,8 @@ void PeakController::saveSettings( QDomDocument & _doc, QDomElement & _this ) void PeakController::loadSettings( const QDomElement & _this ) { + Controller::loadSettings( _this ); + int effectId = _this.attribute( "effectId" ).toInt(); PeakControllerEffectVector::Iterator i; @@ -118,6 +123,75 @@ void PeakController::loadSettings( const QDomElement & _this ) + +//Backward compatibility function for bug in <= 0.4.15 +void PeakController::initGetControllerBySetting() +{ + m_getCount = 0; + m_buggedFile = false; +} + + + + +PeakController * PeakController::getControllerBySetting(const QDomElement & _this ) +{ + int effectId = _this.attribute( "effectId" ).toInt(); + + PeakControllerEffectVector::Iterator i; + + //Backward compatibility for bug in <= 0.4.15 . For >= 1.0.0 , + //foundCount should always be 1 because m_effectId is initialized with rand() + int foundCount = 0; + if( m_buggedFile == false ) + { + for( i = s_effects.begin(); i != s_effects.end(); ++i ) + { + if( (*i)->m_effectId == effectId ) + { + foundCount++; + } + } + if( foundCount >= 2 ) + { + m_buggedFile = true; + int newEffectId = 0; + for( i = s_effects.begin(); i != s_effects.end(); ++i ) + { + (*i)->m_effectId = newEffectId++; + } + QMessageBox msgBox; + msgBox.setIcon( QMessageBox::Information ); + msgBox.setWindowTitle( tr("Peak Controller Bug") ); + msgBox.setText( tr("Due to a bug in older version of LMMS, the peak " + "controllers may not be connect properly. " + "Please ensure that peak controllers are connected " + "properly and re-save this file. " + "Sorry for any inconvenience caused.") ); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.exec(); + } + } + + if( m_buggedFile == true ) + { + effectId = m_getCount; + } + m_getCount++; //NB: m_getCount should be increased even m_buggedFile is false + + for( i = s_effects.begin(); i != s_effects.end(); ++i ) + { + if( (*i)->m_effectId == effectId ) + { + return (*i)->controller(); + } + } + + return NULL; +} + + + QString PeakController::nodeName() const { return( "Peakcontroller" ); diff --git a/src/core/song.cpp b/src/core/song.cpp index c1dfc7392..b1a3763e5 100644 --- a/src/core/song.cpp +++ b/src/core/song.cpp @@ -61,6 +61,7 @@ #include "templates.h" #include "text_float.h" #include "timeline.h" +#include "PeakController.h" #ifdef LMMS_BUILD_WIN32 #ifndef USE_QT_SHMEM @@ -1141,6 +1142,10 @@ void song::loadProject( const QString & _file_name ) m_globalAutomationTrack->restoreState( mmp.content(). firstChildElement( "track" ) ); } + + //Backward compatibility for LMMS <= 0.4.15 + PeakController::initGetControllerBySetting(); + QDomNode node = mmp.content().firstChild(); while( !node.isNull() ) { @@ -1354,7 +1359,16 @@ void song::restoreControllerStates( const QDomElement & _this ) QDomNode node = _this.firstChild(); while( !node.isNull() ) { - addController( Controller::create( node.toElement(), this ) ); + Controller * c = Controller::create( node.toElement(), this ); + Q_ASSERT( c != NULL ); + + /* For PeakController, addController() was called in + * PeakControllerEffect::PeakControllerEffect(). + * This line removes the previously added controller for PeakController + * without affecting the order of controllers in Controller Rack + */ + engine::getSong()->removeController( c ); + addController( c ); node = node.nextSibling(); }