diff --git a/include/AutomatableModel.h b/include/AutomatableModel.h index f390d2531..242b50595 100644 --- a/include/AutomatableModel.h +++ b/include/AutomatableModel.h @@ -206,11 +206,6 @@ public: return "automatablemodel"; } - void prepareJournalEntryFromOldVal(); - - void addJournalEntryFromOldToCurVal(); - - QString displayValue( const float val ) const { switch( m_dataType ) @@ -236,9 +231,6 @@ public slots: protected: - virtual void redoStep( JournalEntry& je ); - virtual void undoStep( JournalEntry& je ); - float fittedValue( float value ) const; @@ -269,7 +261,6 @@ private: // most objects will need this temporarily (until sampleExact is // standard) float m_oldValue; - bool m_journalEntryReady; int m_setValueDepth; AutoModelVector m_linkedModels; diff --git a/include/AutomationPattern.h b/include/AutomationPattern.h index 39dd0cf2a..ca2ff2695 100644 --- a/include/AutomationPattern.h +++ b/include/AutomationPattern.h @@ -27,6 +27,7 @@ #ifndef AUTOMATION_PATTERN_H #define AUTOMATION_PATTERN_H +#include #include #include "track.h" diff --git a/include/JournallingObject.h b/include/JournallingObject.h index df9902546..3f6e47a82 100644 --- a/include/JournallingObject.h +++ b/include/JournallingObject.h @@ -1,7 +1,7 @@ /* * JournallingObject.h - declaration of class JournallingObject * - * Copyright (c) 2006-2009 Tobias Doerffel + * Copyright (c) 2006-2014 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -25,66 +25,10 @@ #ifndef _JOURNALLING_OBJECT_H #define _JOURNALLING_OBJECT_H -#include "lmms_basics.h" -#include "export.h" -#include "SerializingObject.h" - -#include -#include #include - -typedef uint32_t t_action_id; - - -class JournalEntry -{ -public: - JournalEntry( const t_action_id _action_id, const QVariant & _data ) : - m_actionID( _action_id ), - m_data( _data ) - { - } - - JournalEntry() : - m_actionID( 0 ), - m_data( 0 ) - { - } - - ~JournalEntry() - { - } - - t_action_id actionID() const - { - return m_actionID; - } - - t_action_id & actionID() - { - return m_actionID; - } - - const QVariant & data() const - { - return m_data; - } - - QVariant & data() - { - return m_data; - } - - -private: - t_action_id m_actionID; - QVariant m_data; - -} ; - - -typedef QVector JournalEntryVector; +#include "lmms_basics.h" +#include "SerializingObject.h" class EXPORT JournallingObject : public SerializingObject @@ -98,27 +42,10 @@ public: return m_id; } - void undo(); - void redo(); - - void clear() - { - m_journalEntries.clear(); - m_currentJournalEntry = m_journalEntries.end(); - } - - void clearRedoSteps() - { - m_journalEntries.erase( m_currentJournalEntry, - m_journalEntries.end() ); - m_currentJournalEntry = m_journalEntries.end(); - - } - - void saveJournallingState( const bool _new_state ) + void saveJournallingState( const bool newState ) { m_journallingStateStack.push( m_journalling ); - m_journalling = _new_state; + m_journalling = newState; } void restoreJournallingState() @@ -126,12 +53,13 @@ public: m_journalling = m_journallingStateStack.pop(); } + void addJournalCheckPoint(); + virtual QDomElement saveState( QDomDocument & _doc, - QDomElement & _parent ); + QDomElement & _parent ); virtual void restoreState( const QDomElement & _this ); - inline bool isJournalling() const { return m_journalling; @@ -142,10 +70,10 @@ public: m_journalling = _sr; } - inline bool testAndSetJournalling( const bool _sr ) + inline bool testAndSetJournalling( const bool newState ) { const bool oldJournalling = m_journalling; - m_journalling = _sr; + m_journalling = newState; return oldJournalling; } @@ -153,27 +81,10 @@ public: protected: void changeID( jo_id_t _id ); - void addJournalEntry( const JournalEntry & _je ); - - // to be implemented by sub-objects - virtual void undoStep( JournalEntry & ) - { - } - virtual void redoStep( JournalEntry & ) - { - } - private: - void saveJournal( QDomDocument & _doc, QDomElement & _parent ); - void loadJournal( const QDomElement & _this ); - - jo_id_t m_id; - JournalEntryVector m_journalEntries; - JournalEntryVector::Iterator m_currentJournalEntry; - bool m_journalling; QStack m_journallingStateStack; diff --git a/include/ProjectJournal.h b/include/ProjectJournal.h index 041f7507e..011755e45 100644 --- a/include/ProjectJournal.h +++ b/include/ProjectJournal.h @@ -1,7 +1,7 @@ /* * ProjectJournal.h - declaration of class ProjectJournal * - * Copyright (c) 2006-2008 Tobias Doerffel + * Copyright (c) 2006-2010 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -26,10 +26,10 @@ #define _PROJECT_JOURNAL_H #include -#include -#include +#include #include "lmms_basics.h" +#include "DataFile.h" class JournallingObject; @@ -43,8 +43,7 @@ public: void undo(); void redo(); - // tell history that a new journal entry was added to object with ID _id - void journalEntryAdded( const jo_id_t _id ); + void addJournalCheckPoint( JournallingObject *jo ); bool isJournalling() const { @@ -72,10 +71,6 @@ public: reallocID( _id, NULL ); } - // completely remove everything linked with ID _id - all global - // journalling information about the ID get's lost - void forgetAboutID( const jo_id_t _id ); - void clearJournal(); JournallingObject * journallingObject( const jo_id_t _id ) @@ -90,12 +85,23 @@ public: private: typedef QHash JoIdMap; - typedef QVector JournalEntryVector; + + struct CheckPoint + { + CheckPoint( jo_id_t initID = 0, const DataFile&initData = DataFile( DataFile::JournalData ) ) : + joID( initID ), + data( initData ) + { + } + jo_id_t joID; + DataFile data; + } ; + typedef QStack CheckPointStack; JoIdMap m_joIDs; - JournalEntryVector m_journalEntries; - JournalEntryVector::Iterator m_currentJournalEntry; + CheckPointStack m_undoCheckPoints; + CheckPointStack m_redoCheckPoints; bool m_journalling; diff --git a/include/TrackContainerView.h b/include/TrackContainerView.h index 48d8c4957..e1694513e 100644 --- a/include/TrackContainerView.h +++ b/include/TrackContainerView.h @@ -139,9 +139,6 @@ protected: virtual void mouseReleaseEvent( QMouseEvent * _me ); virtual void resizeEvent( QResizeEvent * ); - virtual void undoStep( JournalEntry & _je ); - virtual void redoStep( JournalEntry & _je ); - MidiTime m_currentPosition; diff --git a/include/mmp.h b/include/mmp.h deleted file mode 100644 index d76a8f589..000000000 --- a/include/mmp.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * mmp.h - class for reading and writing multimedia-project-files - * - * Copyright (c) 2004-2014 Tobias Doerffel - * Copyright (c) 2012-2013 Paul Giblock

- * - * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * 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 (see COPYING); if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - */ - - -#ifndef _MMP_H -#define _MMP_H - -#include -#include - -#include "export.h" -#include "lmms_basics.h" - - -class EXPORT multimediaProject : public QDomDocument -{ -public: - enum ProjectTypes - { - UnknownType, - SongProject, - SongProjectTemplate, - InstrumentTrackSettings, - DragNDropData, - ClipboardData, - JournalData, - EffectSettings, - VideoProject, // might come later... - BurnProject, // might come later... - Playlist, // might come later... - NumProjectTypes - } ; - - - multimediaProject( const QString & _fileName ); - multimediaProject( const QByteArray & _data ); - multimediaProject( ProjectTypes _project_type ); - virtual ~multimediaProject(); - - QString nameWithExtension( const QString & _fn ) const; - - void write( QTextStream & _strm ); - bool writeFile( const QString & _fn ); - - inline QDomElement & content() - { - return( m_content ); - } - inline QDomElement & head() - { - return( m_head ); - } - - inline ProjectTypes type() const - { - return( m_type ); - } - - -private: - static ProjectTypes type( const QString & _type_name ); - static QString typeName( ProjectTypes _project_type ); - - void cleanMetaNodes( QDomElement _de ); - - void upgrade(); - - void loadData( const QByteArray & _data, const QString & _sourceFile ); - - - struct EXPORT typeDescStruct - { - ProjectTypes m_type; - QString m_name; - } ; - static typeDescStruct s_types[NumProjectTypes]; - - QDomElement m_content; - QDomElement m_head; - ProjectTypes m_type; - -} ; - - -const int MMP_MAJOR_VERSION = 1; -const int MMP_MINOR_VERSION = 0; -const QString MMP_VERSION_STRING = QString::number( MMP_MAJOR_VERSION ) + "." + QString::number( MMP_MINOR_VERSION ); - - -#endif - diff --git a/include/note.h b/include/note.h index 924ae7bf6..20428b9f8 100644 --- a/include/note.h +++ b/include/note.h @@ -2,7 +2,7 @@ * note.h - declaration of class note which contains all informations about a * note + definitions of several constants and enums * - * Copyright (c) 2004-2010 Tobias Doerffel + * Copyright (c) 2004-2014 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -213,21 +213,8 @@ protected: QDomElement & _parent ); virtual void loadSettings( const QDomElement & _this ); -/* virtual void undoStep( JournalEntry & _je ); - virtual void redoStep( JournalEntry & _je );*/ - private: -/* enum Actions - { - ChangeKey, - ChangeVolume, - ChangePanning, - ChangeLength, - ChangePosition - } ;*/ - - // for piano roll editing bool m_selected; int m_oldKey; diff --git a/include/track.h b/include/track.h index b5a4b3e67..47196e847 100644 --- a/include/track.h +++ b/include/track.h @@ -129,11 +129,6 @@ public slots: void toggleMute(); -protected: - virtual void undoStep( JournalEntry & _je ); - virtual void redoStep( JournalEntry & _je ); - - signals: void lengthChanged(); void positionChanged(); @@ -288,17 +283,8 @@ protected: Q_UNUSED(element) } - virtual void undoStep( JournalEntry & _je ); - virtual void redoStep( JournalEntry & _je ); - private: - enum Actions - { - AddTrackContentObject, - RemoveTrackContentObject - } ; - track * getTrack(); MidiTime getPosition( int _mouse_x ); @@ -550,8 +536,6 @@ public slots: protected: virtual void modelChanged(); - virtual void undoStep( JournalEntry & _je ); - virtual void redoStep( JournalEntry & _je ); virtual void saveSettings( QDomDocument& doc, QDomElement& element ) { diff --git a/plugins/vst_base/VstPlugin.h b/plugins/vst_base/VstPlugin.h index 2c8635bbf..932601dc6 100644 --- a/plugins/vst_base/VstPlugin.h +++ b/plugins/vst_base/VstPlugin.h @@ -25,6 +25,7 @@ #ifndef _VST_PLUGIN_H #define _VST_PLUGIN_H +#include #include #include #include diff --git a/src/core/AutomatableModel.cpp b/src/core/AutomatableModel.cpp index 7a7bc74c4..70cfb9631 100644 --- a/src/core/AutomatableModel.cpp +++ b/src/core/AutomatableModel.cpp @@ -46,7 +46,6 @@ AutomatableModel::AutomatableModel( DataType type, m_step( step ), m_range( max - min ), m_centerValue( m_minValue ), - m_journalEntryReady( false ), m_setValueDepth( 0 ), m_hasLinkedModels( false ), m_controllerConnection( NULL ) @@ -184,7 +183,7 @@ void AutomatableModel::setValue( const float value ) if( old_val != m_value ) { // add changes to history so user can undo it - addJournalEntry( JournalEntry( 0, m_value - old_val ) ); + addJournalCheckPoint(); // notify linked models for( AutoModelVector::Iterator it = m_linkedModels.begin(); it != m_linkedModels.end(); ++it ) @@ -309,51 +308,6 @@ float AutomatableModel::fittedValue( float value ) const -void AutomatableModel::redoStep( JournalEntry& je ) -{ - bool journalling = testAndSetJournalling( false ); - setValue( value() + (float) je.data().toDouble() ); - setJournalling( journalling ); -} - - - - -void AutomatableModel::undoStep( JournalEntry& je ) -{ - JournalEntry inv( je.actionID(), -je.data().toDouble() ); - redoStep( inv ); -} - - - - -void AutomatableModel::prepareJournalEntryFromOldVal() -{ - m_oldValue = value(); - saveJournallingState( false ); - m_journalEntryReady = true; -} - - - - -void AutomatableModel::addJournalEntryFromOldToCurVal() -{ - if( m_journalEntryReady ) - { - restoreJournallingState(); - if( value() != m_oldValue ) - { - addJournalEntry( JournalEntry( 0, value() - m_oldValue ) ); - } - m_journalEntryReady = false; - } -} - - - - void AutomatableModel::linkModel( AutomatableModel* model ) { if( !m_linkedModels.contains( model ) ) diff --git a/src/core/JournallingObject.cpp b/src/core/JournallingObject.cpp index b2a4bc575..ce565551f 100644 --- a/src/core/JournallingObject.cpp +++ b/src/core/JournallingObject.cpp @@ -1,7 +1,7 @@ /* * JournallingObject.cpp - implementation of journalling-object related stuff * - * Copyright (c) 2006-2009 Tobias Doerffel + * Copyright (c) 2006-2014 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -37,8 +37,6 @@ JournallingObject::JournallingObject() : SerializingObject(), m_id( engine::projectJournal()->allocID( this ) ), - m_journalEntries(), - m_currentJournalEntry( m_journalEntries.end() ), m_journalling( true ), m_journallingStateStack() { @@ -58,32 +56,11 @@ JournallingObject::~JournallingObject() -void JournallingObject::undo() +void JournallingObject::addJournalCheckPoint() { - if( m_journalEntries.empty() == true ) + if( isJournalling() ) { - return; - } - - if( m_currentJournalEntry - 1 >= m_journalEntries.begin() ) - { - undoStep( *--m_currentJournalEntry ); - } -} - - - - -void JournallingObject::redo() -{ - if( m_journalEntries.empty() == true ) - { - return; - } - - if( m_currentJournalEntry < m_journalEntries.end() ) - { - redoStep( *m_currentJournalEntry++ ); + engine::projectJournal()->addJournalCheckPoint( this ); } } @@ -94,7 +71,12 @@ QDomElement JournallingObject::saveState( QDomDocument & _doc, QDomElement & _parent ) { QDomElement _this = SerializingObject::saveState( _doc, _parent ); - saveJournal( _doc, _this ); + + QDomElement journalNode = _doc.createElement( "journallingObject" ); + journalNode.setAttribute( "id", id() ); + journalNode.setAttribute( "metadata", true ); + _this.appendChild( journalNode ); + return _this; } @@ -113,7 +95,11 @@ void JournallingObject::restoreState( const QDomElement & _this ) { if( node.isElement() && node.nodeName() == "journal" ) { - loadJournal( node.toElement() ); + const jo_id_t new_id = node.toElement().attribute( "id" ).toInt(); + if( new_id ) + { + changeID( new_id ); + } } node = node.nextSibling(); } @@ -124,21 +110,6 @@ void JournallingObject::restoreState( const QDomElement & _this ) -void JournallingObject::addJournalEntry( const JournalEntry & _je ) -{ - if( engine::projectJournal()->isJournalling() && isJournalling() ) - { - m_journalEntries.erase( m_currentJournalEntry, - m_journalEntries.end() ); - m_journalEntries.push_back( _je ); - m_currentJournalEntry = m_journalEntries.end(); - engine::projectJournal()->journalEntryAdded( id() ); - } -} - - - - void JournallingObject::changeID( jo_id_t _id ) { if( id() != _id ) @@ -159,78 +130,10 @@ void JournallingObject::changeID( jo_id_t _id ) (int) _id, used_by.toUtf8().constData() ); return; } - engine::projectJournal()->forgetAboutID( id() ); + engine::projectJournal()->reallocID( _id, this ); m_id = _id; } } - - -void JournallingObject::saveJournal( QDomDocument & _doc, - QDomElement & _parent ) -{ -/* // avoid creating empty journal-nodes - if( m_journalEntries.size() == 0 ) - { - return; - }*/ - QDomElement journal_de = _doc.createElement( "journal" ); - journal_de.setAttribute( "id", id() ); - journal_de.setAttribute( "entries", m_journalEntries.size() ); - journal_de.setAttribute( "curentry", (int)( m_currentJournalEntry - - m_journalEntries.begin() ) ); - journal_de.setAttribute( "metadata", true ); - - for( JournalEntryVector::const_iterator it = m_journalEntries.begin(); - it != m_journalEntries.end(); ++it ) - { - QDomElement je_de = _doc.createElement( "entry" ); - je_de.setAttribute( "pos", (int)( it - - m_journalEntries.begin() ) ); - je_de.setAttribute( "actionid", it->actionID() ); - je_de.setAttribute( "data", base64::encode( it->data() ) ); - journal_de.appendChild( je_de ); - } - - _parent.appendChild( journal_de ); -} - - - - -void JournallingObject::loadJournal( const QDomElement & _this ) -{ - clear(); - - const jo_id_t new_id = _this.attribute( "id" ).toInt(); - - if( new_id == 0 ) - { - return; - } - - changeID( new_id ); - - m_journalEntries.resize( _this.attribute( "entries" ).toInt() ); - - QDomNode node = _this.firstChild(); - while( !node.isNull() ) - { - if( node.isElement() ) - { - const QDomElement & je = node.toElement(); - m_journalEntries[je.attribute( "pos" ).toInt()] = - JournalEntry( - je.attribute( "actionid" ).toInt(), - base64::decode( je.attribute( "data" ) ) ); - } - node = node.nextSibling(); - } - - m_currentJournalEntry = m_journalEntries.begin() + - _this.attribute( "curentry" ).toInt(); -} - - diff --git a/src/core/ProjectJournal.cpp b/src/core/ProjectJournal.cpp index dffd60eee..2c5c0d912 100644 --- a/src/core/ProjectJournal.cpp +++ b/src/core/ProjectJournal.cpp @@ -1,7 +1,7 @@ /* * ProjectJournal.cpp - implementation of ProjectJournal * - * Copyright (c) 2006-2009 Tobias Doerffel + * Copyright (c) 2006-2014 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -32,8 +32,8 @@ ProjectJournal::ProjectJournal() : m_joIDs(), - m_journalEntries(), - m_currentJournalEntry( m_journalEntries.end() ), + m_undoCheckPoints(), + m_redoCheckPoints(), m_journalling( false ) { } @@ -50,51 +50,66 @@ ProjectJournal::~ProjectJournal() void ProjectJournal::undo() { - if( m_journalEntries.empty() == true ) + while( !m_undoCheckPoints.isEmpty() ) { - return; - } + CheckPoint c = m_undoCheckPoints.pop(); + JournallingObject *jo = m_joIDs[c.joID]; - JournallingObject * jo; + if( jo ) + { + DataFile curState( DataFile::JournalData ); + jo->saveState( curState, curState.content() ); + m_redoCheckPoints.push( CheckPoint( c.joID, curState ) ); - if( m_currentJournalEntry - 1 >= m_journalEntries.begin() && - ( jo = m_joIDs[*--m_currentJournalEntry] ) != NULL ) - { - jo->undo(); - engine::getSong()->setModified(); + bool prev = isJournalling(); + setJournalling( false ); + jo->restoreState( c.data.content().firstChildElement() ); + setJournalling( prev ); + engine::getSong()->setModified(); + break; + } } } - void ProjectJournal::redo() { - if( m_journalEntries.empty() == true ) + while( !m_redoCheckPoints.isEmpty() ) { - return; - } + CheckPoint c = m_redoCheckPoints.pop(); + JournallingObject *jo = m_joIDs[c.joID]; - JournallingObject * jo; + if( jo ) + { + DataFile curState( DataFile::JournalData ); + jo->saveState( curState, curState.content() ); + m_undoCheckPoints.push( CheckPoint( c.joID, curState ) ); - //printf("%d\n", m_joIDs[*(m_currentJournalEntry+1)] ); - if( m_currentJournalEntry < m_journalEntries.end() && - ( jo = m_joIDs[*m_currentJournalEntry++] ) != NULL ) - { - jo->redo(); - engine::getSong()->setModified(); + bool prev = isJournalling(); + setJournalling( false ); + jo->restoreState( c.data.content().firstChildElement() ); + setJournalling( prev ); + engine::getSong()->setModified(); + break; + } } } -void ProjectJournal::journalEntryAdded( const jo_id_t _id ) +void ProjectJournal::addJournalCheckPoint( JournallingObject *jo ) { - m_journalEntries.erase( m_currentJournalEntry, m_journalEntries.end() ); - m_journalEntries.push_back( _id ); - m_currentJournalEntry = m_journalEntries.end(); - engine::getSong()->setModified(); + if( isJournalling() ) + { + m_redoCheckPoints.clear(); + + DataFile dataFile( DataFile::JournalData ); + jo->saveState( dataFile, dataFile.content() ); + + m_undoCheckPoints.push( CheckPoint( jo->id(), dataFile ) ); + } } @@ -130,29 +145,11 @@ void ProjectJournal::reallocID( const jo_id_t _id, JournallingObject * _obj ) -void ProjectJournal::forgetAboutID( const jo_id_t _id ) -{ - //printf("forget about %d\n", _id ); - JournalEntryVector::Iterator it; - while( ( it = qFind( m_journalEntries.begin(), m_journalEntries.end(), - _id ) ) != m_journalEntries.end() ) - { - if( m_currentJournalEntry >= it ) - { - --m_currentJournalEntry; - } - m_journalEntries.erase( it ); - } - m_joIDs.remove( _id ); -} - - - - void ProjectJournal::clearJournal() { - m_journalEntries.clear(); - m_currentJournalEntry = m_journalEntries.end(); + m_undoCheckPoints.clear(); + m_redoCheckPoints.clear(); + for( JoIdMap::Iterator it = m_joIDs.begin(); it != m_joIDs.end(); ) { if( it.value() == NULL ) diff --git a/src/core/TrackContainer.cpp b/src/core/TrackContainer.cpp index c2430918e..4c4b69c85 100644 --- a/src/core/TrackContainer.cpp +++ b/src/core/TrackContainer.cpp @@ -73,10 +73,16 @@ void TrackContainer::saveSettings( QDomDocument & _doc, QDomElement & _this ) void TrackContainer::loadSettings( const QDomElement & _this ) { + bool journalRestore = _this.parentNode().nodeName() == "journaldata"; + if( journalRestore ) + { + clearAllTracks(); + } + static QProgressDialog * pd = NULL; bool was_null = ( pd == NULL ); int start_val = 0; - if( engine::hasGUI() ) + if( !journalRestore && engine::hasGUI() ) { if( pd == NULL ) { @@ -154,6 +160,8 @@ void TrackContainer::addTrack( track * _track ) { if( _track->type() != track::HiddenAutomationTrack ) { + addJournalCheckPoint(); + m_tracksMutex.lockForWrite(); m_tracks.push_back( _track ); m_tracksMutex.unlock(); diff --git a/src/core/note.cpp b/src/core/note.cpp index 0b67f4a35..791f022a3 100644 --- a/src/core/note.cpp +++ b/src/core/note.cpp @@ -1,7 +1,7 @@ /* * note.cpp - implementation of class note * - * Copyright (c) 2004-2009 Tobias Doerffel + * Copyright (c) 2004-2014 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -50,13 +50,14 @@ note::note( const MidiTime & _length, const MidiTime & _pos, m_pos( _pos ), m_detuning( NULL ) { - //saveJournallingState( false ); -// setJournalling( false ); if( _detuning ) { m_detuning = sharedObject::ref( _detuning ); } - //restoreJournallingState(); + else + { + createDetuning(); + } } @@ -98,7 +99,6 @@ note::~note() void note::setLength( const MidiTime & _length ) { -// addJournalEntry( journalEntry( ChangeLength, m_length - _length ) ); m_length = _length; } @@ -107,7 +107,6 @@ void note::setLength( const MidiTime & _length ) void note::setPos( const MidiTime & _pos ) { -// addJournalEntry( journalEntry( ChangePosition, m_pos - _pos ) ); m_pos = _pos; } @@ -117,7 +116,6 @@ void note::setPos( const MidiTime & _pos ) void note::setKey( const int _key ) { const int k = qBound( 0, _key, NumKeys ); -// addJournalEntry( journalEntry( ChangeKey, m_key - k ) ); m_key = k; } @@ -127,7 +125,6 @@ void note::setKey( const int _key ) void note::setVolume( volume_t _volume ) { const volume_t v = qBound( MinVolume, _volume, MaxVolume ); -// addJournalEntry( journalEntry( ChangeVolume, (int) m_volume - v ) ); m_volume = v; } @@ -137,7 +134,6 @@ void note::setVolume( volume_t _volume ) void note::setPanning( panning_t _panning ) { const panning_t p = qBound( PanningLeft, _panning, PanningRight ); -// addJournalEntry( journalEntry( ChangePanning, (int) m_panning - p ) ); m_panning = p; } @@ -213,46 +209,6 @@ void note::loadSettings( const QDomElement & _this ) -/*void note::undoStep( journalEntry & _je ) -{ - saveJournallingState( false ); - switch( static_cast( _je.actionID() ) ) - { - case ChangeKey: - setKey( key() - _je.data().toInt() ); - break; - - case ChangeVolume: - setVolume( getVolume() - _je.data().toInt() ); - break; - - case ChangePanning: - setPanning( getPanning() - _je.data().toInt() ); - break; - - case ChangeLength: - setLength( length() - _je.data().toInt() ); - break; - - case ChangePosition: - setPos( pos() - _je.data().toInt() ); - break; - } - restoreJournallingState(); -} - - - - -void note::redoStep( journalEntry & _je ) -{ - journalEntry je( _je.actionID(), -_je.data().toInt() ); - undoStep( je ); -}*/ - - - - void note::editDetuningPattern() { createDetuning(); diff --git a/src/core/track.cpp b/src/core/track.cpp index 66452bfa6..5bdf09f7f 100644 --- a/src/core/track.cpp +++ b/src/core/track.cpp @@ -149,7 +149,6 @@ void trackContentObject::movePosition( const MidiTime & _pos ) { if( m_startPosition != _pos ) { - addJournalEntry( JournalEntry( Move, m_startPosition - _pos ) ); m_startPosition = _pos; engine::getSong()->updateLength(); } @@ -170,7 +169,6 @@ void trackContentObject::changeLength( const MidiTime & _length ) { if( m_length != _length ) { - addJournalEntry( JournalEntry( Resize, m_length - _length ) ); m_length = _length; engine::getSong()->updateLength(); } @@ -180,47 +178,6 @@ void trackContentObject::changeLength( const MidiTime & _length ) -/*! \brief Undo one journal entry of this trackContentObject - * - * Restore the previous state of this track content object. This will - * restore the position or the length of the track content object - * depending on what was changed. - * - * \param _je The journal entry to undo - */ -void trackContentObject::undoStep( JournalEntry & _je ) -{ - saveJournallingState( false ); - switch( _je.actionID() ) - { - case Move: - movePosition( startPosition() + _je.data().toInt() ); - break; - case Resize: - changeLength( length() + _je.data().toInt() ); - break; - } - restoreJournallingState(); -} - - - - -/*! \brief Redo one journal entry of this trackContentObject - * - * Undoes one 'undo' of this track content object. - * - * \param _je The journal entry to redo - */ -void trackContentObject::redoStep( JournalEntry & _je ) -{ - JournalEntry je( _je.actionID(), -_je.data().toInt() ); - undoStep( je ); -} - - - - /*! \brief Copy this trackContentObject to the clipboard. * * Copies this track content object to the clipboard. @@ -367,6 +324,8 @@ bool trackContentObjectView::fixedTCOs() */ bool trackContentObjectView::close() { + m_trackView->getTrack()->addJournalCheckPoint(); + m_trackView->getTrackContentWidget()->removeTCOView( this ); return QWidget::close(); } @@ -577,6 +536,8 @@ void trackContentObjectView::mousePressEvent( QMouseEvent * _me ) /* engine::mainWindow()->isShiftPressed() == false &&*/ fixedTCOs() == false ) { + m_tco->addJournalCheckPoint(); + // move or resize m_tco->setJournalling( false ); @@ -770,9 +731,6 @@ void trackContentObjectView::mouseReleaseEvent( QMouseEvent * _me ) if( m_action == Move || m_action == Resize ) { m_tco->setJournalling( true ); - m_tco->addJournalEntry( JournalEntry( m_action, m_oldTime - - ( ( m_action == Move ) ? - m_tco->startPosition() : m_tco->length() ) ) ); } m_action = NoAction; delete m_hint; @@ -945,9 +903,6 @@ void trackContentWidget::updateBackground() void trackContentWidget::addTCOView( trackContentObjectView * _tcov ) { trackContentObject * tco = _tcov->getTrackContentObject(); -/* QMap map; - map["id"] = tco->id(); - addJournalEntry( JournalEntry( AddTrackContentObject, map ) );*/ m_tcoViews.push_back( _tcov ); @@ -972,14 +927,6 @@ void trackContentWidget::removeTCOView( trackContentObjectView * _tcov ) _tcov ); if( it != m_tcoViews.end() ) { -/* QMap map; - DataFile dataFile( DataFile::JournalData ); - _tcov->getTrackContentObject()->saveState( dataFile, dataFile.content() ); - map["id"] = _tcov->getTrackContentObject()->id(); - map["state"] = dataFile.toString(); - addJournalEntry( JournalEntry( RemoveTrackContentObject, - map ) );*/ - m_tcoViews.erase( it ); engine::getSong()->setModified(); } @@ -1121,6 +1068,7 @@ void trackContentWidget::dropEvent( QDropEvent * _de ) { const MidiTime pos = getPosition( _de->pos().x() ).toNearestTact(); + getTrack()->addJournalCheckPoint(); trackContentObject * tco = getTrack()->createTCO( pos ); // value contains our XML-data so simply create a @@ -1209,71 +1157,6 @@ void trackContentWidget::resizeEvent( QResizeEvent * resizeEvent ) -/*! \brief Undo an action on the trackContentWidget - * - * \param _je the details of the edit journal - */ -void trackContentWidget::undoStep( JournalEntry & _je ) -{ - saveJournallingState( false ); - switch( _je.actionID() ) - { - case AddTrackContentObject: - { - QMap map = _je.data().toMap(); - trackContentObject * tco = - dynamic_cast( - engine::projectJournal()->journallingObject( map["id"].toInt() ) ); - DataFile dataFile( DataFile::JournalData ); - tco->saveState( dataFile, dataFile.content() ); - map["state"] = dataFile.toString(); - _je.data() = map; - tco->deleteLater(); - break; - } - - case RemoveTrackContentObject: - { - trackContentObject * tco = getTrack()->createTCO( MidiTime( 0 ) ); - DataFile dataFile( - _je.data().toMap()["state"]. - toString().toUtf8() ); - tco->restoreState( dataFile.content().firstChild().toElement() ); - break; - } - } - restoreJournallingState(); -} - - - - -/*! \brief Redo an action of the trackContentWidget - * - * \param _je the entry in the edit journal to redo. - */ -void trackContentWidget::redoStep( JournalEntry & _je ) -{ - switch( _je.actionID() ) - { - case AddTrackContentObject: - case RemoveTrackContentObject: - _je.actionID() = ( _je.actionID() == - AddTrackContentObject ) ? - RemoveTrackContentObject : - AddTrackContentObject; - undoStep( _je ); - _je.actionID() = ( _je.actionID() == - AddTrackContentObject ) ? - RemoveTrackContentObject : - AddTrackContentObject; - break; - } -} - - - - /*! \brief Return the track shown by the trackContentWidget * */ @@ -2227,55 +2110,6 @@ void trackView::modelChanged() -/*! \brief Undo a change to this track View. - * - * \param _je the Journal Entry to undo. - */ -void trackView::undoStep( JournalEntry & _je ) -{ - saveJournallingState( false ); - switch( _je.actionID() ) - { - case MoveTrack: - if( _je.data().toInt() > 0 ) - { - m_trackContainerView->moveTrackViewUp( this ); - } - else - { - m_trackContainerView->moveTrackViewDown( this ); - } - break; - case ResizeTrack: - setFixedHeight( qMax( height() + - _je.data().toInt(), - MINIMAL_TRACK_HEIGHT ) ); - m_trackContainerView->realignTracks(); - break; - /*case RestoreTrack: - setFixedHeight( DEFAULT_TRACK_HEIGHT ); - m_trackContainerView->realignTracks(); - break; */ - } - restoreJournallingState(); -} - - - - -/*! \brief Redo a change to this track View. - * - * \param _je the Journal Event to redo. - */ -void trackView::redoStep( JournalEntry & _je ) -{ - JournalEntry je( _je.actionID(), -_je.data().toInt() ); - undoStep( je ); -} - - - - /*! \brief Start a drag event on this track View. * * \param _dee the DragEnterEvent to start. @@ -2412,6 +2246,7 @@ void trackView::mouseMoveEvent( QMouseEvent * _me ) // a track-widget not equal to ourself? if( track_at_y != NULL && track_at_y != this ) { + addJournalCheckPoint(); // then move us up/down there! if( _me->y() < 0 ) { @@ -2421,7 +2256,6 @@ void trackView::mouseMoveEvent( QMouseEvent * _me ) { m_trackContainerView->moveTrackViewDown( this ); } - addJournalEntry( JournalEntry( MoveTrack, _me->y() ) ); } } else if( m_action == ResizeTrack ) diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index eb6dcf188..b5359bbd2 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -279,7 +279,7 @@ void MainWindow::finalize() QMenu * edit_menu = new QMenu( this ); menuBar()->addMenu( edit_menu )->setText( tr( "&Edit" ) ); -/* edit_menu->addAction( embed::getIconPixmap( "edit_undo" ), + edit_menu->addAction( embed::getIconPixmap( "edit_undo" ), tr( "Undo" ), this, SLOT( undo() ), Qt::CTRL + Qt::Key_Z ); @@ -287,7 +287,7 @@ void MainWindow::finalize() tr( "Redo" ), this, SLOT( redo() ), Qt::CTRL + Qt::Key_R ); - edit_menu->addSeparator();*/ + edit_menu->addSeparator(); edit_menu->addAction( embed::getIconPixmap( "setup_general" ), tr( "Settings" ), this, SLOT( showSettingsDialog() ) ); diff --git a/src/gui/PianoRoll.cpp b/src/gui/PianoRoll.cpp index c09524152..b0960bb23 100644 --- a/src/gui/PianoRoll.cpp +++ b/src/gui/PianoRoll.cpp @@ -1395,6 +1395,15 @@ void PianoRoll::keyReleaseEvent( QKeyEvent* event ) m_editMode = m_ctrlMode; update(); break; + + // update after undo/redo + case Qt::Key_Z: + case Qt::Key_R: + if( validPattern() && event->modifiers() == Qt::ControlModifier ) + { + update(); + } + break; } update(); @@ -1562,6 +1571,7 @@ void PianoRoll::mousePressEvent( QMouseEvent * _me ) // area if( edit_note == true ) { + m_pattern->addJournalCheckPoint(); // scribble note edit changes mouseMoveEvent( _me ); return; @@ -1579,6 +1589,7 @@ void PianoRoll::mousePressEvent( QMouseEvent * _me ) if( it == notes.begin()-1 ) { is_new_note = true; + m_pattern->addJournalCheckPoint(); m_pattern->setType( pattern::MelodyPattern ); // then set new note @@ -1624,8 +1635,7 @@ void PianoRoll::mousePressEvent( QMouseEvent * _me ) // ops (move, resize) after this // code-block it = notes.begin(); - while( it != notes.end() && - *it != created_new_note ) + while( it != notes.end() && *it != created_new_note ) { ++it; } @@ -1701,6 +1711,7 @@ void PianoRoll::mousePressEvent( QMouseEvent * _me ) ( m_currentNote->pos() + m_currentNote->length() )*m_ppt/ MidiTime::ticksPerTact() - RESIZE_AREA_WIDTH && m_currentNote->length() > 0 ) { + m_pattern->addJournalCheckPoint(); // then resize the note m_action = ActionResizeNote; @@ -1710,6 +1721,11 @@ void PianoRoll::mousePressEvent( QMouseEvent * _me ) } else { + if( !created_new_note ) + { + m_pattern->addJournalCheckPoint(); + } + // otherwise move it m_action = ActionMoveNote; @@ -1765,6 +1781,7 @@ void PianoRoll::mousePressEvent( QMouseEvent * _me ) m_mouseDownRight = true; if( it != notes.begin()-1 ) { + m_pattern->addJournalCheckPoint(); if( ( *it )->length() > 0 ) { m_pattern->removeNote( *it ); @@ -2589,7 +2606,6 @@ void PianoRoll::dragNotes( int x, int y, bool alt, bool shift ) if( ( *it )->selected() ) { - if( m_action == ActionMoveNote ) { // moving note @@ -3677,6 +3693,11 @@ void PianoRoll::pasteNotes() // remove selection and select the newly pasted notes clearSelectedNotes(); + if( !list.isEmpty() ) + { + m_pattern->addJournalCheckPoint(); + } + for( int i = 0; !list.item( i ).isNull(); ++i ) { // create the note @@ -3713,7 +3734,8 @@ void PianoRoll::deleteSelectedNotes() bool update_after_delete = false; - + m_pattern->addJournalCheckPoint(); + // get note-vector of current pattern const NoteVector & notes = m_pattern->notes(); diff --git a/src/gui/TrackContainerView.cpp b/src/gui/TrackContainerView.cpp index bfcbd62f9..775a56ece 100644 --- a/src/gui/TrackContainerView.cpp +++ b/src/gui/TrackContainerView.cpp @@ -121,10 +121,6 @@ void TrackContainerView::loadSettings( const QDomElement & _this ) trackView * TrackContainerView::addTrackView( trackView * _tv ) { -/* QMap map; - map["id"] = _tv->getTrack()->id(); - addJournalEntry( JournalEntry( AddTrack, map ) );*/ - m_trackViews.push_back( _tv ); m_scrollLayout->addWidget( _tv ); connect( this, SIGNAL( positionChanged( const MidiTime & ) ), @@ -142,13 +138,6 @@ void TrackContainerView::removeTrackView( trackView * _tv ) int index = m_trackViews.indexOf( _tv ); if( index != -1 ) { -/* QMap map; - DataFile dataFile( DataFile::JournalData ); - _tv->getTrack()->saveState( dataFile, dataFile.content() ); - map["id"] = _tv->getTrack()->id(); - map["state"] = dataFile.toString(); - addJournalEntry( JournalEntry( RemoveTrack, map ) );*/ - m_trackViews.removeAt( index ); disconnect( _tv ); @@ -238,6 +227,8 @@ void TrackContainerView::createTrackView( track * _t ) void TrackContainerView::deleteTrackView( trackView * _tv ) { + m_tc->addJournalCheckPoint(); + track * t = _tv->getTrack(); removeTrackView( _tv ); delete _tv; @@ -311,64 +302,6 @@ void TrackContainerView::clearAllTracks() -void TrackContainerView::undoStep( JournalEntry & _je ) -{ -#if 0 - saveJournallingState( false ); - switch( _je.actionID() ) - { - case AddTrack: - { - QMap map = _je.data().toMap(); - track * t = - dynamic_cast( - engine::projectJournal()->getJournallingObject( - map["id"].toInt() ) ); - assert( t != NULL ); - DataFile dataFile( DataFile::JournalData ); - t->saveState( dataFile, dataFile.content() ); - map["state"] = dataFile.toString(); - _je.data() = map; - t->deleteLater(); - break; - } - - case RemoveTrack: - { - DataFile dataFile( - _je.data().toMap()["state"].toString().utf8() ); - track::create( dataFile.content().firstChild().toElement(), - m_tc ); - break; - } - } - restoreJournallingState(); -#endif -} - - - - -void TrackContainerView::redoStep( JournalEntry & _je ) -{ -#if 0 - switch( _je.actionID() ) - { - case AddTrack: - case RemoveTrack: - _je.actionID() = ( _je.actionID() == AddTrack ) ? - RemoveTrack : AddTrack; - undoStep( _je ); - _je.actionID() = ( _je.actionID() == AddTrack ) ? - RemoveTrack : AddTrack; - break; - } -#endif -} - - - - void TrackContainerView::dragEnterEvent( QDragEnterEvent * _dee ) { stringPairDrag::processDragEnterEvent( _dee, diff --git a/src/gui/widgets/LcdSpinBox.cpp b/src/gui/widgets/LcdSpinBox.cpp index 3c638c5d5..03632e6fc 100644 --- a/src/gui/widgets/LcdSpinBox.cpp +++ b/src/gui/widgets/LcdSpinBox.cpp @@ -104,7 +104,13 @@ void LcdSpinBox::mousePressEvent( QMouseEvent* event ) m_mouseMoving = true; m_origMousePos = event->globalPos(); QApplication::setOverrideCursor( Qt::BlankCursor ); - model()->prepareJournalEntryFromOldVal(); + + AutomatableModel *thisModel = model(); + if( thisModel ) + { + thisModel->addJournalCheckPoint(); + thisModel->saveJournallingState( false ); + } } else { @@ -139,7 +145,7 @@ void LcdSpinBox::mouseReleaseEvent( QMouseEvent* ) { if( m_mouseMoving ) { - model()->addJournalEntryFromOldToCurVal(); + model()->restoreJournallingState(); QCursor::setPos( m_origMousePos ); QApplication::restoreOverrideCursor(); diff --git a/src/gui/widgets/knob.cpp b/src/gui/widgets/knob.cpp index 008ad62d2..fc33abea3 100644 --- a/src/gui/widgets/knob.cpp +++ b/src/gui/widgets/knob.cpp @@ -467,7 +467,12 @@ void knob::mousePressEvent( QMouseEvent * _me ) ! ( _me->modifiers() & Qt::ControlModifier ) && ! ( _me->modifiers() & Qt::ShiftModifier ) ) { - model()->prepareJournalEntryFromOldVal(); + AutomatableModel *thisModel = model(); + if( thisModel ) + { + thisModel->addJournalCheckPoint(); + thisModel->saveJournallingState( false ); + } const QPoint & p = _me->pos(); m_origMousePos = p; @@ -515,9 +520,16 @@ void knob::mouseMoveEvent( QMouseEvent * _me ) -void knob::mouseReleaseEvent( QMouseEvent * /* _me*/ ) +void knob::mouseReleaseEvent( QMouseEvent* event ) { - model()->addJournalEntryFromOldToCurVal(); + if( event && event->button() == Qt::LeftButton ) + { + AutomatableModel *thisModel = model(); + if( thisModel ) + { + thisModel->restoreJournallingState(); + } + } m_buttonPressed = false;