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:
@@ -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;
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#ifndef AUTOMATION_PATTERN_H
|
||||
#define AUTOMATION_PATTERN_H
|
||||
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QPointer>
|
||||
|
||||
#include "track.h"
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
|
||||
113
include/mmp.h
113
include/mmp.h
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#ifndef _VST_PLUGIN_H
|
||||
#define _VST_PLUGIN_H
|
||||
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QMutex>
|
||||
#include <QtCore/QPointer>
|
||||
#include <QtCore/QString>
|
||||
|
||||
@@ -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 ) )
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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() ) );
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user