diff --git a/include/JournallingObject.h b/include/JournallingObject.h index 84731c07c..1be811d20 100644 --- a/include/JournallingObject.h +++ b/include/JournallingObject.h @@ -27,7 +27,6 @@ #include "lmms_basics.h" #include "export.h" -#include "mmp.h" #include "SerializingObject.h" #include @@ -35,39 +34,6 @@ #include -class JournalCheckPoint -{ -public: - JournalCheckPoint( const multimediaProject &data = - multimediaProject( multimediaProject::JournalData ) ) : - m_data( data ) - { - } - - ~JournalCheckPoint() - { - } - - const multimediaProject &data() const - { - return m_data; - } - - multimediaProject &data() - { - return m_data; - } - - -private: - multimediaProject m_data; - -} ; - - -typedef QVector JournalCheckPointVector; - - class EXPORT JournallingObject : public SerializingObject { public: @@ -79,27 +45,10 @@ public: return m_id; } - void undo(); - void redo(); - - void clear() - { - m_journalCheckPoints.clear(); - m_currentJournalCheckPoint = m_journalCheckPoints.end(); - } - - void clearRedoSteps() - { - m_journalCheckPoints.erase( m_currentJournalCheckPoint, - m_journalCheckPoints.end() ); - m_currentJournalCheckPoint = m_journalCheckPoints.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() @@ -110,11 +59,10 @@ public: void addJournalCheckPoint(); virtual QDomElement saveState( QDomDocument & _doc, - QDomElement & _parent ); + QDomElement & _parent ); virtual void restoreState( const QDomElement & _this ); - inline bool isJournalling() const { return m_journalling; @@ -125,10 +73,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; } @@ -138,15 +86,8 @@ protected: private: - void saveJournal( QDomDocument & _doc, QDomElement & _parent ); - void loadJournal( const QDomElement & _this ); - - jo_id_t m_id; - JournalCheckPointVector m_journalCheckPoints; - JournalCheckPointVector::Iterator m_currentJournalCheckPoint; - bool m_journalling; QStack m_journallingStateStack; diff --git a/include/ProjectJournal.h b/include/ProjectJournal.h index 041f7507e..7c819daa0 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 "mmp.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,25 @@ public: private: typedef QHash JoIdMap; - typedef QVector JournalEntryVector; + + struct CheckPoint + { + CheckPoint( jo_id_t initID = 0, + const multimediaProject &initData = + multimediaProject( multimediaProject::JournalData ) ) : + joID( initID ), + data( initData ) + { + } + jo_id_t joID; + multimediaProject 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/src/core/JournallingObject.cpp b/src/core/JournallingObject.cpp index 7d3229597..ce565551f 100644 --- a/src/core/JournallingObject.cpp +++ b/src/core/JournallingObject.cpp @@ -37,8 +37,6 @@ JournallingObject::JournallingObject() : SerializingObject(), m_id( engine::projectJournal()->allocID( this ) ), - m_journalCheckPoints(), - m_currentJournalCheckPoint( m_journalCheckPoints.end() ), m_journalling( true ), m_journallingStateStack() { @@ -58,34 +56,11 @@ JournallingObject::~JournallingObject() -void JournallingObject::undo() +void JournallingObject::addJournalCheckPoint() { - if( m_journalCheckPoints.empty() == true ) + if( isJournalling() ) { - return; - } - - if( m_currentJournalCheckPoint - 1 >= m_journalCheckPoints.begin() ) - { - --m_currentJournalCheckPoint; - restoreState( m_currentJournalCheckPoint->data().content().firstChildElement() ); - } -} - - - - -void JournallingObject::redo() -{ - if( m_journalCheckPoints.empty() == true ) - { - return; - } - - if( m_currentJournalCheckPoint < m_journalCheckPoints.end() ) - { - restoreState( m_currentJournalCheckPoint->data().content().firstChildElement() ); - ++m_currentJournalCheckPoint; + engine::projectJournal()->addJournalCheckPoint( this ); } } @@ -96,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; } @@ -115,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(); } @@ -126,26 +110,6 @@ void JournallingObject::restoreState( const QDomElement & _this ) -void JournallingObject::addJournalCheckPoint() -{ - if( engine::projectJournal()->isJournalling() && isJournalling() ) - { - m_journalCheckPoints.erase( m_currentJournalCheckPoint, - m_journalCheckPoints.end() ); - - multimediaProject mmp( multimediaProject::JournalData ); - saveState( mmp, mmp.content() ); - - m_journalCheckPoints.push_back( JournalCheckPoint( mmp ) ); - - m_currentJournalCheckPoint = m_journalCheckPoints.end(); - engine::projectJournal()->journalEntryAdded( id() ); - } -} - - - - void JournallingObject::changeID( jo_id_t _id ) { if( id() != _id ) @@ -166,77 +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_journalCheckPoints.size() == 0 ) - { - return; - }*/ - QDomElement journal_de = _doc.createElement( "journal" ); - journal_de.setAttribute( "id", id() ); - journal_de.setAttribute( "entries", m_journalCheckPoints.size() ); - journal_de.setAttribute( "curentry", (int)( m_currentJournalCheckPoint - - m_journalCheckPoints.begin() ) ); - journal_de.setAttribute( "metadata", true ); - - for( JournalCheckPointVector::const_iterator it = m_journalCheckPoints.begin(); - it != m_journalCheckPoints.end(); ++it ) - { - QDomElement je_de = _doc.createElement( "entry" ); - je_de.setAttribute( "pos", (int)( it - - m_journalCheckPoints.begin() ) ); - //je_de.setAttribute( "data", base64::encode( it->data().toString() ) ); - je_de.setAttribute( "data", it->data().toString() ); - 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_journalCheckPoints.resize( _this.attribute( "entries" ).toInt() ); - - QDomNode node = _this.firstChild(); - while( !node.isNull() ) - { - if( node.isElement() ) - { - const QDomElement & je = node.toElement(); - m_journalCheckPoints[je.attribute( "pos" ).toInt()] = - JournalCheckPoint( - multimediaProject( je.attribute( "data" ).toUtf8() ) ); - } - node = node.nextSibling(); - } - - m_currentJournalCheckPoint = m_journalCheckPoints.begin() + - _this.attribute( "curentry" ).toInt(); -} - - diff --git a/src/core/ProjectJournal.cpp b/src/core/ProjectJournal.cpp index 04e452fde..bcd30d807 100644 --- a/src/core/ProjectJournal.cpp +++ b/src/core/ProjectJournal.cpp @@ -32,8 +32,8 @@ ProjectJournal::ProjectJournal() : m_joIDs(), - m_journalEntries(), - m_currentJournalEntry( m_journalEntries.end() ), + m_undoCheckPoints(), + m_redoCheckPoints(), m_journalling( false ) { } @@ -50,57 +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 ) + { + multimediaProject curState( multimediaProject::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 ) - { - bool prev = isJournalling(); - setJournalling( false ); - jo->undo(); - setJournalling( prev ); - 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 ) + { + multimediaProject curState( multimediaProject::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 ) - { - bool prev = isJournalling(); - setJournalling( false ); - jo->redo(); - setJournalling( prev ); - 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(); + + multimediaProject mmp( multimediaProject::JournalData ); + jo->saveState( mmp, mmp.content() ); + + m_undoCheckPoints.push( CheckPoint( jo->id(), mmp ) ); + } } @@ -136,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 )