Revised journalling (undo/redo) to record full states instead of changes
Recording single changes of objects or their specific properties is completely superfluous as we have full implemented state tracking in all objects already. Therefore use SerializingObject::saveState() and SerializingObject::restoreState() in order to implement the undo/redo functionality. This is just an initial commit and needs some further work (especially regarding stability). However even things like undo/redo of addition/removal of Tracks and TrackContentObjects do work already.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* AutomatableModel.h - declaration of class AutomatableModel
|
||||
*
|
||||
* Copyright (c) 2007-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
* Copyright (c) 2007-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
|
||||
*
|
||||
@@ -180,23 +180,19 @@ public:
|
||||
static void unlinkModels( AutomatableModel * _m1,
|
||||
AutomatableModel * _m2 );
|
||||
|
||||
virtual void saveSettings( QDomDocument & _doc,
|
||||
QDomElement & _this,
|
||||
const QString & _name = QString( "value" ) );
|
||||
virtual void saveSettings( QDomDocument &doc, QDomElement &_this );
|
||||
virtual void loadSettings( const QDomElement &_this );
|
||||
|
||||
virtual void loadSettings( const QDomElement & _this,
|
||||
const QString & _name = QString( "value" ) );
|
||||
virtual void saveSettings( QDomDocument &doc,
|
||||
QDomElement &_this,
|
||||
const QString &name );
|
||||
virtual void loadSettings( const QDomElement &_this, const QString &name );
|
||||
|
||||
virtual QString nodeName() const
|
||||
{
|
||||
return "automatablemodel";
|
||||
}
|
||||
|
||||
void prepareJournalEntryFromOldVal();
|
||||
|
||||
void addJournalEntryFromOldToCurVal();
|
||||
|
||||
|
||||
QString displayValue( const float _val ) const
|
||||
{
|
||||
switch( m_dataType )
|
||||
@@ -217,9 +213,6 @@ public slots:
|
||||
|
||||
|
||||
protected:
|
||||
virtual void redoStep( JournalEntry & _je );
|
||||
virtual void undoStep( JournalEntry & _je );
|
||||
|
||||
float fittedValue( float _value ) const;
|
||||
|
||||
|
||||
@@ -239,7 +232,6 @@ private:
|
||||
// most objects will need this temporarily (until sampleExact is
|
||||
// standard)
|
||||
float m_oldValue;
|
||||
bool m_journalEntryReady;
|
||||
int m_setValueDepth;
|
||||
|
||||
AutoModelVector m_linkedModels;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* JournallingObject.h - declaration of class JournallingObject
|
||||
*
|
||||
* Copyright (c) 2006-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
* Copyright (c) 2006-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
|
||||
*
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
#include "lmms_basics.h"
|
||||
#include "export.h"
|
||||
#include "mmp.h"
|
||||
#include "SerializingObject.h"
|
||||
|
||||
#include <QtCore/QVariant>
|
||||
@@ -34,57 +35,37 @@
|
||||
#include <QtCore/QStack>
|
||||
|
||||
|
||||
typedef uint32_t t_action_id;
|
||||
|
||||
|
||||
class JournalEntry
|
||||
class JournalCheckPoint
|
||||
{
|
||||
public:
|
||||
JournalEntry( const t_action_id _action_id, const QVariant & _data ) :
|
||||
m_actionID( _action_id ),
|
||||
m_data( _data )
|
||||
JournalCheckPoint( const multimediaProject &data =
|
||||
multimediaProject( multimediaProject::JournalData ) ) :
|
||||
m_data( data )
|
||||
{
|
||||
}
|
||||
|
||||
JournalEntry() :
|
||||
m_actionID( 0 ),
|
||||
m_data( 0 )
|
||||
~JournalCheckPoint()
|
||||
{
|
||||
}
|
||||
|
||||
~JournalEntry()
|
||||
{
|
||||
}
|
||||
|
||||
t_action_id actionID() const
|
||||
{
|
||||
return m_actionID;
|
||||
}
|
||||
|
||||
t_action_id & actionID()
|
||||
{
|
||||
return m_actionID;
|
||||
}
|
||||
|
||||
const QVariant & data() const
|
||||
const multimediaProject &data() const
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
QVariant & data()
|
||||
multimediaProject &data()
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
t_action_id m_actionID;
|
||||
QVariant m_data;
|
||||
multimediaProject m_data;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
typedef QVector<JournalEntry> JournalEntryVector;
|
||||
typedef QVector<JournalCheckPoint> JournalCheckPointVector;
|
||||
|
||||
|
||||
class EXPORT JournallingObject : public SerializingObject
|
||||
@@ -103,15 +84,15 @@ public:
|
||||
|
||||
void clear()
|
||||
{
|
||||
m_journalEntries.clear();
|
||||
m_currentJournalEntry = m_journalEntries.end();
|
||||
m_journalCheckPoints.clear();
|
||||
m_currentJournalCheckPoint = m_journalCheckPoints.end();
|
||||
}
|
||||
|
||||
void clearRedoSteps()
|
||||
{
|
||||
m_journalEntries.erase( m_currentJournalEntry,
|
||||
m_journalEntries.end() );
|
||||
m_currentJournalEntry = m_journalEntries.end();
|
||||
m_journalCheckPoints.erase( m_currentJournalCheckPoint,
|
||||
m_journalCheckPoints.end() );
|
||||
m_currentJournalCheckPoint = m_journalCheckPoints.end();
|
||||
|
||||
}
|
||||
|
||||
@@ -126,6 +107,8 @@ public:
|
||||
m_journalling = m_journallingStateStack.pop();
|
||||
}
|
||||
|
||||
void addJournalCheckPoint();
|
||||
|
||||
virtual QDomElement saveState( QDomDocument & _doc,
|
||||
QDomElement & _parent );
|
||||
|
||||
@@ -153,16 +136,6 @@ 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 );
|
||||
@@ -171,8 +144,8 @@ private:
|
||||
|
||||
jo_id_t m_id;
|
||||
|
||||
JournalEntryVector m_journalEntries;
|
||||
JournalEntryVector::Iterator m_currentJournalEntry;
|
||||
JournalCheckPointVector m_journalCheckPoints;
|
||||
JournalCheckPointVector::Iterator m_currentJournalCheckPoint;
|
||||
|
||||
bool m_journalling;
|
||||
|
||||
|
||||
@@ -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 <tobydox/at/users.sourceforge.net>
|
||||
* Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
|
||||
*
|
||||
@@ -208,21 +208,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;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* position of a channel + calculation of volume for each
|
||||
* speaker
|
||||
*
|
||||
* Copyright (c) 2004-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
* Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
|
||||
*
|
||||
@@ -57,18 +57,6 @@ public:
|
||||
void loadSettings( const QDomElement & _this,
|
||||
const QString & _name = "surpos" );
|
||||
|
||||
inline void prepareJournalEntryFromOldVal()
|
||||
{
|
||||
m_posX.prepareJournalEntryFromOldVal();
|
||||
m_posY.prepareJournalEntryFromOldVal();
|
||||
}
|
||||
|
||||
inline void addJournalEntryFromOldToCurVal()
|
||||
{
|
||||
m_posX.addJournalEntryFromOldToCurVal();
|
||||
m_posY.addJournalEntryFromOldToCurVal();
|
||||
}
|
||||
|
||||
// AutomationPattern * automationPatternX();
|
||||
// AutomationPattern * automationPatternY();
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* track.h - declaration of classes concerning tracks -> necessary for all
|
||||
* track-like objects (beat/bassline, sample-track...)
|
||||
*
|
||||
* Copyright (c) 2004-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
* Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
|
||||
*
|
||||
@@ -128,11 +128,6 @@ public slots:
|
||||
void toggleMute();
|
||||
|
||||
|
||||
protected:
|
||||
virtual void undoStep( JournalEntry & _je );
|
||||
virtual void redoStep( JournalEntry & _je );
|
||||
|
||||
|
||||
signals:
|
||||
void lengthChanged();
|
||||
void positionChanged();
|
||||
@@ -275,17 +270,8 @@ protected:
|
||||
return "trackcontentwidget";
|
||||
}
|
||||
|
||||
virtual void undoStep( JournalEntry & _je );
|
||||
virtual void redoStep( JournalEntry & _je );
|
||||
|
||||
|
||||
private:
|
||||
enum Actions
|
||||
{
|
||||
AddTrackContentObject,
|
||||
RemoveTrackContentObject
|
||||
} ;
|
||||
|
||||
track * getTrack();
|
||||
midiTime getPosition( int _mouse_x );
|
||||
|
||||
@@ -539,8 +525,6 @@ public slots:
|
||||
|
||||
protected:
|
||||
virtual void modelChanged();
|
||||
virtual void undoStep( JournalEntry & _je );
|
||||
virtual void redoStep( JournalEntry & _je );
|
||||
|
||||
virtual QString nodeName() const
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* track_container_view.h - view-component for trackContainer
|
||||
*
|
||||
* Copyright (c) 2004-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
* Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
|
||||
*
|
||||
@@ -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;
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* AutomatableModel.cpp - some implementations of AutomatableModel-class
|
||||
*
|
||||
* Copyright (c) 2008-2012 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
* Copyright (c) 2008-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
|
||||
*
|
||||
@@ -50,7 +50,6 @@ AutomatableModel::AutomatableModel( DataType _type,
|
||||
m_maxValue( _max ),
|
||||
m_step( _step ),
|
||||
m_range( _max - _min ),
|
||||
m_journalEntryReady( false ),
|
||||
m_setValueDepth( 0 ),
|
||||
m_hasLinkedModels( false ),
|
||||
m_controllerConnection( NULL )
|
||||
@@ -88,6 +87,22 @@ bool AutomatableModel::isAutomated() const
|
||||
|
||||
|
||||
|
||||
void AutomatableModel::saveSettings( QDomDocument &doc, QDomElement &_this )
|
||||
{
|
||||
saveSettings( doc, _this, "value" );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void AutomatableModel::loadSettings( const QDomElement &_this )
|
||||
{
|
||||
loadSettings( _this, "value" );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void AutomatableModel::saveSettings( QDomDocument & _doc, QDomElement & _this,
|
||||
const QString & _name )
|
||||
{
|
||||
@@ -184,7 +199,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 =
|
||||
@@ -319,52 +334,6 @@ float AutomatableModel::fittedValue( float _value ) const
|
||||
|
||||
|
||||
|
||||
void AutomatableModel::redoStep( JournalEntry & _je )
|
||||
{
|
||||
bool journalling = testAndSetJournalling( false );
|
||||
setValue( value<float>() + (float) _je.data().toDouble() );
|
||||
setJournalling( journalling );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void AutomatableModel::undoStep( JournalEntry & _je )
|
||||
{
|
||||
JournalEntry je( _je.actionID(), -_je.data().toDouble() );
|
||||
redoStep( je );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void AutomatableModel::prepareJournalEntryFromOldVal()
|
||||
{
|
||||
m_oldValue = value<float>();
|
||||
saveJournallingState( false );
|
||||
m_journalEntryReady = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void AutomatableModel::addJournalEntryFromOldToCurVal()
|
||||
{
|
||||
if( m_journalEntryReady )
|
||||
{
|
||||
restoreJournallingState();
|
||||
if( value<float>() != m_oldValue )
|
||||
{
|
||||
addJournalEntry( JournalEntry( 0, value<float>() -
|
||||
m_oldValue ) );
|
||||
}
|
||||
m_journalEntryReady = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void AutomatableModel::linkModel( AutomatableModel * _model )
|
||||
{
|
||||
if( !m_linkedModels.contains( _model ) )
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* JournallingObject.cpp - implementation of journalling-object related stuff
|
||||
*
|
||||
* Copyright (c) 2006-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
* Copyright (c) 2006-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
|
||||
*
|
||||
@@ -37,8 +37,8 @@
|
||||
JournallingObject::JournallingObject() :
|
||||
SerializingObject(),
|
||||
m_id( engine::projectJournal()->allocID( this ) ),
|
||||
m_journalEntries(),
|
||||
m_currentJournalEntry( m_journalEntries.end() ),
|
||||
m_journalCheckPoints(),
|
||||
m_currentJournalCheckPoint( m_journalCheckPoints.end() ),
|
||||
m_journalling( true ),
|
||||
m_journallingStateStack()
|
||||
{
|
||||
@@ -60,14 +60,15 @@ JournallingObject::~JournallingObject()
|
||||
|
||||
void JournallingObject::undo()
|
||||
{
|
||||
if( m_journalEntries.empty() == true )
|
||||
if( m_journalCheckPoints.empty() == true )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( m_currentJournalEntry - 1 >= m_journalEntries.begin() )
|
||||
if( m_currentJournalCheckPoint - 1 >= m_journalCheckPoints.begin() )
|
||||
{
|
||||
undoStep( *--m_currentJournalEntry );
|
||||
--m_currentJournalCheckPoint;
|
||||
restoreState( m_currentJournalCheckPoint->data().content().firstChildElement() );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,14 +77,15 @@ void JournallingObject::undo()
|
||||
|
||||
void JournallingObject::redo()
|
||||
{
|
||||
if( m_journalEntries.empty() == true )
|
||||
if( m_journalCheckPoints.empty() == true )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( m_currentJournalEntry < m_journalEntries.end() )
|
||||
if( m_currentJournalCheckPoint < m_journalCheckPoints.end() )
|
||||
{
|
||||
redoStep( *m_currentJournalEntry++ );
|
||||
restoreState( m_currentJournalCheckPoint->data().content().firstChildElement() );
|
||||
++m_currentJournalCheckPoint;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,14 +126,19 @@ void JournallingObject::restoreState( const QDomElement & _this )
|
||||
|
||||
|
||||
|
||||
void JournallingObject::addJournalEntry( const JournalEntry & _je )
|
||||
void JournallingObject::addJournalCheckPoint()
|
||||
{
|
||||
if( engine::projectJournal()->isJournalling() && isJournalling() )
|
||||
{
|
||||
m_journalEntries.erase( m_currentJournalEntry,
|
||||
m_journalEntries.end() );
|
||||
m_journalEntries.push_back( _je );
|
||||
m_currentJournalEntry = m_journalEntries.end();
|
||||
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() );
|
||||
}
|
||||
}
|
||||
@@ -172,25 +179,25 @@ void JournallingObject::saveJournal( QDomDocument & _doc,
|
||||
QDomElement & _parent )
|
||||
{
|
||||
/* // avoid creating empty journal-nodes
|
||||
if( m_journalEntries.size() == 0 )
|
||||
if( m_journalCheckPoints.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( "entries", m_journalCheckPoints.size() );
|
||||
journal_de.setAttribute( "curentry", (int)( m_currentJournalCheckPoint -
|
||||
m_journalCheckPoints.begin() ) );
|
||||
journal_de.setAttribute( "metadata", true );
|
||||
|
||||
for( JournalEntryVector::const_iterator it = m_journalEntries.begin();
|
||||
it != m_journalEntries.end(); ++it )
|
||||
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_journalEntries.begin() ) );
|
||||
je_de.setAttribute( "actionid", it->actionID() );
|
||||
je_de.setAttribute( "data", base64::encode( it->data() ) );
|
||||
m_journalCheckPoints.begin() ) );
|
||||
//je_de.setAttribute( "data", base64::encode( it->data().toString() ) );
|
||||
je_de.setAttribute( "data", it->data().toString() );
|
||||
journal_de.appendChild( je_de );
|
||||
}
|
||||
|
||||
@@ -213,7 +220,7 @@ void JournallingObject::loadJournal( const QDomElement & _this )
|
||||
|
||||
changeID( new_id );
|
||||
|
||||
m_journalEntries.resize( _this.attribute( "entries" ).toInt() );
|
||||
m_journalCheckPoints.resize( _this.attribute( "entries" ).toInt() );
|
||||
|
||||
QDomNode node = _this.firstChild();
|
||||
while( !node.isNull() )
|
||||
@@ -221,15 +228,14 @@ void JournallingObject::loadJournal( const QDomElement & _this )
|
||||
if( node.isElement() )
|
||||
{
|
||||
const QDomElement & je = node.toElement();
|
||||
m_journalEntries[je.attribute( "pos" ).toInt()] =
|
||||
JournalEntry(
|
||||
je.attribute( "actionid" ).toInt(),
|
||||
base64::decode( je.attribute( "data" ) ) );
|
||||
m_journalCheckPoints[je.attribute( "pos" ).toInt()] =
|
||||
JournalCheckPoint(
|
||||
multimediaProject( je.attribute( "data" ).toUtf8() ) );
|
||||
}
|
||||
node = node.nextSibling();
|
||||
}
|
||||
}
|
||||
|
||||
m_currentJournalEntry = m_journalEntries.begin() +
|
||||
m_currentJournalCheckPoint = m_journalCheckPoints.begin() +
|
||||
_this.attribute( "curentry" ).toInt();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* ProjectJournal.cpp - implementation of ProjectJournal
|
||||
*
|
||||
* Copyright (c) 2006-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
* Copyright (c) 2006-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
|
||||
*
|
||||
@@ -60,7 +60,10 @@ void ProjectJournal::undo()
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -81,7 +84,10 @@ void ProjectJournal::redo()
|
||||
if( m_currentJournalEntry < m_journalEntries.end() &&
|
||||
( jo = m_joIDs[*m_currentJournalEntry++] ) != NULL )
|
||||
{
|
||||
bool prev = isJournalling();
|
||||
setJournalling( false );
|
||||
jo->redo();
|
||||
setJournalling( prev );
|
||||
engine::getSong()->setModified();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* note.cpp - implementation of class note
|
||||
*
|
||||
* Copyright (c) 2004-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
* Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
|
||||
*
|
||||
@@ -50,8 +50,6 @@ 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 );
|
||||
@@ -60,7 +58,6 @@ note::note( const midiTime & _length, const midiTime & _pos,
|
||||
{
|
||||
createDetuning();
|
||||
}
|
||||
//restoreJournallingState();
|
||||
}
|
||||
|
||||
|
||||
@@ -106,7 +103,6 @@ note::~note()
|
||||
|
||||
void note::setLength( const midiTime & _length )
|
||||
{
|
||||
// addJournalEntry( journalEntry( ChangeLength, m_length - _length ) );
|
||||
m_length = _length;
|
||||
}
|
||||
|
||||
@@ -115,7 +111,6 @@ void note::setLength( const midiTime & _length )
|
||||
|
||||
void note::setPos( const midiTime & _pos )
|
||||
{
|
||||
// addJournalEntry( journalEntry( ChangePosition, m_pos - _pos ) );
|
||||
m_pos = _pos;
|
||||
}
|
||||
|
||||
@@ -125,7 +120,6 @@ void note::setPos( const midiTime & _pos )
|
||||
void note::setKey( const int _key )
|
||||
{
|
||||
const int k = tLimit( _key, 0, NumKeys );
|
||||
// addJournalEntry( journalEntry( ChangeKey, m_key - k ) );
|
||||
m_key = k;
|
||||
}
|
||||
|
||||
@@ -135,7 +129,6 @@ void note::setKey( const int _key )
|
||||
void note::setVolume( const volume_t _volume )
|
||||
{
|
||||
const volume_t v = tLimit( _volume, MinVolume, MaxVolume );
|
||||
// addJournalEntry( journalEntry( ChangeVolume, (int) m_volume - v ) );
|
||||
m_volume = v;
|
||||
}
|
||||
|
||||
@@ -145,7 +138,6 @@ void note::setVolume( const volume_t _volume )
|
||||
void note::setPanning( const panning_t _panning )
|
||||
{
|
||||
const panning_t p = tLimit( _panning, PanningLeft, PanningRight );
|
||||
// addJournalEntry( journalEntry( ChangePanning, (int) m_panning - p ) );
|
||||
m_panning = p;
|
||||
}
|
||||
|
||||
@@ -219,46 +211,6 @@ void note::loadSettings( const QDomElement & _this )
|
||||
|
||||
|
||||
|
||||
/*void note::undoStep( journalEntry & _je )
|
||||
{
|
||||
saveJournallingState( false );
|
||||
switch( static_cast<Actions>( _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()
|
||||
{
|
||||
m_detuning->automationPattern()->openInAutomationEditor();
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* track.cpp - implementation of classes concerning tracks -> necessary for
|
||||
* all track-like objects (beat/bassline, sample-track...)
|
||||
*
|
||||
* Copyright (c) 2004-2012 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
* Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
|
||||
*
|
||||
@@ -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 );
|
||||
|
||||
@@ -773,9 +734,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;
|
||||
@@ -951,9 +909,6 @@ void trackContentWidget::updateBackground()
|
||||
void trackContentWidget::addTCOView( trackContentObjectView * _tcov )
|
||||
{
|
||||
trackContentObject * tco = _tcov->getTrackContentObject();
|
||||
/* QMap<QString, QVariant> map;
|
||||
map["id"] = tco->id();
|
||||
addJournalEntry( JournalEntry( AddTrackContentObject, map ) );*/
|
||||
|
||||
m_tcoViews.push_back( _tcov );
|
||||
|
||||
@@ -978,14 +933,6 @@ void trackContentWidget::removeTCOView( trackContentObjectView * _tcov )
|
||||
_tcov );
|
||||
if( it != m_tcoViews.end() )
|
||||
{
|
||||
/* QMap<QString, QVariant> map;
|
||||
multimediaProject mmp( multimediaProject::JournalData );
|
||||
_tcov->getTrackContentObject()->saveState( mmp, mmp.content() );
|
||||
map["id"] = _tcov->getTrackContentObject()->id();
|
||||
map["state"] = mmp.toString();
|
||||
addJournalEntry( JournalEntry( RemoveTrackContentObject,
|
||||
map ) );*/
|
||||
|
||||
m_tcoViews.erase( it );
|
||||
engine::getSong()->setModified();
|
||||
}
|
||||
@@ -1127,6 +1074,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
|
||||
@@ -1167,6 +1115,7 @@ void trackContentWidget::mousePressEvent( QMouseEvent * _me )
|
||||
{
|
||||
const midiTime pos = getPosition( _me->x() ).getTact() *
|
||||
midiTime::ticksPerTact();
|
||||
getTrack()->addJournalCheckPoint();
|
||||
trackContentObject * tco = getTrack()->createTCO( pos );
|
||||
|
||||
tco->saveJournallingState( false );
|
||||
@@ -1215,71 +1164,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<QString, QVariant> map = _je.data().toMap();
|
||||
trackContentObject * tco =
|
||||
dynamic_cast<trackContentObject *>(
|
||||
engine::projectJournal()->journallingObject( map["id"].toInt() ) );
|
||||
multimediaProject mmp( multimediaProject::JournalData );
|
||||
tco->saveState( mmp, mmp.content() );
|
||||
map["state"] = mmp.toString();
|
||||
_je.data() = map;
|
||||
tco->deleteLater();
|
||||
break;
|
||||
}
|
||||
|
||||
case RemoveTrackContentObject:
|
||||
{
|
||||
trackContentObject * tco = getTrack()->createTCO( midiTime( 0 ) );
|
||||
multimediaProject mmp(
|
||||
_je.data().toMap()["state"].
|
||||
toString().toUtf8() );
|
||||
tco->restoreState( mmp.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
|
||||
*
|
||||
*/
|
||||
@@ -2231,55 +2115,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<int>( 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.
|
||||
@@ -2414,6 +2249,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 )
|
||||
{
|
||||
@@ -2423,7 +2259,6 @@ void trackView::mouseMoveEvent( QMouseEvent * _me )
|
||||
{
|
||||
m_trackContainerView->moveTrackViewDown( this );
|
||||
}
|
||||
addJournalEntry( JournalEntry( MoveTrack, _me->y() ) );
|
||||
}
|
||||
}
|
||||
else if( m_action == ResizeTrack )
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* track_container.cpp - implementation of base-class for all track-containers
|
||||
* like Song-Editor, BB-Editor...
|
||||
*
|
||||
* Copyright (c) 2004-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
* Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
|
||||
*
|
||||
@@ -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();
|
||||
|
||||
@@ -121,10 +121,6 @@ void trackContainerView::loadSettings( const QDomElement & _this )
|
||||
|
||||
trackView * trackContainerView::addTrackView( trackView * _tv )
|
||||
{
|
||||
/* QMap<QString, QVariant> 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<QString, QVariant> map;
|
||||
multimediaProject mmp( multimediaProject::JournalData );
|
||||
_tv->getTrack()->saveState( mmp, mmp.content() );
|
||||
map["id"] = _tv->getTrack()->id();
|
||||
map["state"] = mmp.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;
|
||||
@@ -307,64 +298,6 @@ void trackContainerView::clearAllTracks()
|
||||
|
||||
|
||||
|
||||
void trackContainerView::undoStep( JournalEntry & _je )
|
||||
{
|
||||
#if 0
|
||||
saveJournallingState( false );
|
||||
switch( _je.actionID() )
|
||||
{
|
||||
case AddTrack:
|
||||
{
|
||||
QMap<QString, QVariant> map = _je.data().toMap();
|
||||
track * t =
|
||||
dynamic_cast<track *>(
|
||||
engine::projectJournal()->getJournallingObject(
|
||||
map["id"].toInt() ) );
|
||||
assert( t != NULL );
|
||||
multimediaProject mmp( multimediaProject::JournalData );
|
||||
t->saveState( mmp, mmp.content() );
|
||||
map["state"] = mmp.toString();
|
||||
_je.data() = map;
|
||||
t->deleteLater();
|
||||
break;
|
||||
}
|
||||
|
||||
case RemoveTrack:
|
||||
{
|
||||
multimediaProject mmp(
|
||||
_je.data().toMap()["state"].toString().utf8() );
|
||||
track::create( mmp.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,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* knob.cpp - powerful knob-widget
|
||||
*
|
||||
* Copyright (c) 2004-2011 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
* Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
|
||||
*
|
||||
@@ -438,7 +438,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;
|
||||
@@ -485,7 +490,7 @@ void knob::mouseMoveEvent( QMouseEvent * _me )
|
||||
|
||||
void knob::mouseReleaseEvent( QMouseEvent * /* _me*/ )
|
||||
{
|
||||
model()->addJournalEntryFromOldToCurVal();
|
||||
model()->restoreJournallingState();
|
||||
|
||||
m_buttonPressed = false;
|
||||
|
||||
|
||||
@@ -100,7 +100,13 @@ void lcdSpinBox::mousePressEvent( QMouseEvent* event )
|
||||
{
|
||||
m_origMousePos = event->globalPos();
|
||||
QApplication::setOverrideCursor( Qt::BlankCursor );
|
||||
model()->prepareJournalEntryFromOldVal();
|
||||
|
||||
AutomatableModel *thisModel = model();
|
||||
if( thisModel )
|
||||
{
|
||||
thisModel->addJournalCheckPoint();
|
||||
thisModel->saveJournallingState( false );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -131,7 +137,12 @@ void lcdSpinBox::mouseMoveEvent( QMouseEvent* event )
|
||||
|
||||
void lcdSpinBox::mouseReleaseEvent( QMouseEvent* event )
|
||||
{
|
||||
model()->addJournalEntryFromOldToCurVal();
|
||||
AutomatableModel *thisModel = model();
|
||||
if( thisModel )
|
||||
{
|
||||
thisModel->restoreJournallingState();
|
||||
}
|
||||
|
||||
|
||||
QCursor::setPos( m_origMousePos );
|
||||
QApplication::restoreOverrideCursor();
|
||||
|
||||
Reference in New Issue
Block a user