Merge remote-tracking branch 'origin/stable-0.4-undo-redo'

Conflicts:
	include/AutomatableModel.h
	include/MidiPort.h
	include/TrackContainerView.h
	include/surround_area.h
	include/track.h
	src/core/AutomatableModel.cpp
	src/core/TrackContainer.cpp
	src/core/note.cpp
	src/core/track.cpp
	src/gui/PianoRoll.cpp
	src/gui/TrackContainerView.cpp
	src/gui/widgets/LcdSpinBox.cpp
This commit is contained in:
Tobias Doerffel
2014-03-24 19:37:26 +01:00
20 changed files with 167 additions and 777 deletions

View File

@@ -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;

View File

@@ -27,6 +27,7 @@
#ifndef AUTOMATION_PATTERN_H
#define AUTOMATION_PATTERN_H
#include <QtCore/QMap>
#include <QtCore/QPointer>
#include "track.h"

View File

@@ -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
*
@@ -25,66 +25,10 @@
#ifndef _JOURNALLING_OBJECT_H
#define _JOURNALLING_OBJECT_H
#include "lmms_basics.h"
#include "export.h"
#include "SerializingObject.h"
#include <QtCore/QVariant>
#include <QtCore/QVector>
#include <QtCore/QStack>
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<JournalEntry> 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<bool> m_journallingStateStack;

View File

@@ -1,7 +1,7 @@
/*
* ProjectJournal.h - declaration of class ProjectJournal
*
* Copyright (c) 2006-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2006-2010 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -26,10 +26,10 @@
#define _PROJECT_JOURNAL_H
#include <QtCore/QHash>
#include <QtCore/QVariant>
#include <QtCore/QVector>
#include <QtCore/QStack>
#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<jo_id_t, JournallingObject *> JoIdMap;
typedef QVector<jo_id_t> 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<CheckPoint> CheckPointStack;
JoIdMap m_joIDs;
JournalEntryVector m_journalEntries;
JournalEntryVector::Iterator m_currentJournalEntry;
CheckPointStack m_undoCheckPoints;
CheckPointStack m_redoCheckPoints;
bool m_journalling;

View File

@@ -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;

View File

@@ -1,113 +0,0 @@
/*
* mmp.h - class for reading and writing multimedia-project-files
*
* Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2012-2013 Paul Giblock <p/at/pgiblock.net>
*
* 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 <QtXml/QDomDocument>
#include <QTextStream>
#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

View File

@@ -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
*
@@ -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;

View File

@@ -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 )
{

View File

@@ -25,6 +25,7 @@
#ifndef _VST_PLUGIN_H
#define _VST_PLUGIN_H
#include <QtCore/QMap>
#include <QtCore/QMutex>
#include <QtCore/QPointer>
#include <QtCore/QString>

View File

@@ -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>() + (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<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 ) )

View File

@@ -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,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();
}

View File

@@ -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
*
@@ -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 )

View File

@@ -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();

View File

@@ -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,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<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()
{
createDetuning();

View File

@@ -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<QString, QVariant> 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<QString, QVariant> 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<QString, QVariant> map = _je.data().toMap();
trackContentObject * tco =
dynamic_cast<trackContentObject *>(
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<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.
@@ -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 )

View File

@@ -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() ) );

View File

@@ -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();

View File

@@ -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;
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<QString, QVariant> map = _je.data().toMap();
track * t =
dynamic_cast<track *>(
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,

View File

@@ -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();

View File

@@ -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;