From b951d8b192eaa0e348f3dd3d067da245775b20f1 Mon Sep 17 00:00:00 2001 From: Hugo Beauzee-Luyssen Date: Fri, 11 Dec 2009 19:03:25 +0100 Subject: [PATCH] Undo redo is functionnal for clip resizing --- src/Actions/StackedAction.hpp | 22 +++++++++++++++++++ src/Commands/Commands.cpp | 31 +++++++++++++++++---------- src/Commands/Commands.h | 30 ++++++++++++++++++++------ src/GUI/AbstractGraphicsMediaItem.cpp | 13 +++++++++-- src/GUI/TracksView.cpp | 7 ++++++ src/GUI/TracksView.h | 2 ++ src/Media/Clip.cpp | 2 ++ src/Renderer/WorkflowRenderer.cpp | 13 +++++++++-- src/Renderer/WorkflowRenderer.h | 7 +++++- src/Workflow/MainWorkflow.h | 1 + 10 files changed, 106 insertions(+), 22 deletions(-) diff --git a/src/Actions/StackedAction.hpp b/src/Actions/StackedAction.hpp index 87e7fbf2..db00cd51 100644 --- a/src/Actions/StackedAction.hpp +++ b/src/Actions/StackedAction.hpp @@ -39,6 +39,7 @@ namespace Action Resize, Remove, Add, + Move, }; Generic( Type type ) : m_type( type ) {} virtual ~Generic(){} @@ -108,6 +109,27 @@ namespace Action QUuid m_uuid; }; + class MoveClip : public Track + { + public: + MoveClip( MainWorkflow* mainWorkflow, const QUuid& uuid, uint32_t oldTrack, + uint32_t newTrack, qint64 newPos, MainWorkflow::TrackType trackType, bool undoRedoAction ) : + Track( mainWorkflow, oldTrack, trackType, Move ), + m_uuid( uuid ), m_newTrack( newTrack ), + m_newPos( newPos ), m_undoRedoAction( undoRedoAction ) + { + } + void execute() + { + m_mainWorkflow->moveClip( m_uuid, m_trackId, m_newTrack, m_newPos, m_trackType, m_undoRedoAction ); + } + private: + QUuid m_uuid; + uint32_t m_newTrack; + qint64 m_newPos; + bool m_undoRedoAction; + }; + class ResizeClip : public Generic { public: diff --git a/src/Commands/Commands.cpp b/src/Commands/Commands.cpp index a69d0c0b..4835551a 100644 --- a/src/Commands/Commands.cpp +++ b/src/Commands/Commands.cpp @@ -102,28 +102,37 @@ void Commands::MainWorkflow::RemoveClips::undo() m_renderer->addClip( m_clips.at( i ).clip, m_clips.at( i ).trackNumber, m_clips.at( i ).pos, m_clips.at( i ).trackType ); } -Commands::MainWorkflow::ResizeClip::ResizeClip( ::MainWorkflow* mainWorkflow, const QUuid& uuid, unsigned int trackId, - qint64 newBegin, qint64 newEnd, ::MainWorkflow::TrackType trackType ) : - m_mainWorkflow( mainWorkflow ), +Commands::MainWorkflow::ResizeClip::ResizeClip( WorkflowRenderer* renderer, const QUuid& uuid, + qint64 newBegin, qint64 newEnd, + qint64 oldBegin, qint64 oldEnd, + qint64 newPos, qint64 oldPos, + uint32_t trackId, + ::MainWorkflow::TrackType trackType ) : + m_renderer( renderer ), + m_uuid( uuid ), m_newBegin( newBegin ), m_newEnd( newEnd ), - m_trackType( trackType ) + m_oldBegin( oldBegin ), + m_oldEnd( oldEnd ), + m_newPos( newPos ), + m_oldPos( oldPos ), + m_trackId( trackId ), + m_trackType( trackType ), + m_undoRedoAction( false ) { - m_clip = mainWorkflow->getClip( uuid, trackId, m_trackType ); - m_oldBegin = m_clip->getBegin(); - m_oldEnd = m_clip->getEnd(); + m_clip = ::MainWorkflow::getInstance()->getClip( uuid, trackId, m_trackType ); + setText( QObject::tr( "Resizing clip" ) ); } void Commands::MainWorkflow::ResizeClip::redo() { - m_clip->setBegin( m_newBegin ); - m_clip->setEnd( m_newEnd ); + m_renderer->resizeClip( m_clip, m_newBegin, m_newEnd, m_newPos, m_trackId, m_trackType, m_undoRedoAction ); + m_undoRedoAction = true; } void Commands::MainWorkflow::ResizeClip::undo() { - m_clip->setBegin( m_oldBegin ); - m_clip->setEnd( m_oldEnd ); + m_renderer->resizeClip( m_clip, m_oldBegin, m_oldEnd, m_oldPos, m_trackId, m_trackType, m_undoRedoAction ); } Commands::MainWorkflow::SplitClip::SplitClip( WorkflowRenderer* renderer, Clip* toSplit, uint32_t trackId, diff --git a/src/Commands/Commands.h b/src/Commands/Commands.h index 6ed84be1..60600d04 100644 --- a/src/Commands/Commands.h +++ b/src/Commands/Commands.h @@ -95,22 +95,40 @@ namespace Commands QVector m_clips; }; + /** + * \brief This command is used to resize a clip. + * \param renderer: The workflow renderer + * \param uuid: The clip's uuid + * \param newBegin: The clip's new beginning + * \param newEnd: The clip's new end + * \param newPos: if the clip was resized from the beginning, it is moved + * so we have to know its new position + * \param trackId:The track in which the modification occurs. This is only + * used when the clip is resized from the beginning. + * \param trackType: The track's type (Audio or Video) + */ NEW_COMMAND( ResizeClip ) { public: - ResizeClip( ::MainWorkflow* mainWorkflow, const QUuid& uuid, unsigned int trackId, - qint64 newBegin, qint64 newEnd, - ::MainWorkflow::TrackType trackType ); + ResizeClip( WorkflowRenderer* renderer, const QUuid& uuid, + qint64 newBegin, qint64 newEnd, qint64 oldBegin, + qint64 oldEnd, qint64 newPos, qint64 oldPos, + uint32_t trackId, ::MainWorkflow::TrackType trackType ); virtual void redo(); virtual void undo(); private: - ::MainWorkflow* m_mainWorkflow; - qint64 m_oldBegin; - qint64 m_oldEnd; + WorkflowRenderer* m_renderer; + QUuid m_uuid; qint64 m_newBegin; qint64 m_newEnd; + qint64 m_oldBegin; + qint64 m_oldEnd; + qint64 m_newPos; + qint64 m_oldPos; + uint32_t m_trackId; Clip* m_clip; ::MainWorkflow::TrackType m_trackType; + bool m_undoRedoAction; }; NEW_COMMAND( SplitClip ) diff --git a/src/GUI/AbstractGraphicsMediaItem.cpp b/src/GUI/AbstractGraphicsMediaItem.cpp index fbde0671..bd6c94d5 100644 --- a/src/GUI/AbstractGraphicsMediaItem.cpp +++ b/src/GUI/AbstractGraphicsMediaItem.cpp @@ -21,6 +21,9 @@ *****************************************************************************/ #include "AbstractGraphicsMediaItem.h" +#include "TracksView.h" + +#include "Commands.h" AbstractGraphicsMediaItem::AbstractGraphicsMediaItem() : oldTrackNumber( -1 ), oldPosition( -1 ), m_tracksView( NULL ), @@ -106,7 +109,11 @@ void AbstractGraphicsMediaItem::resize( qint64 size, From from ) if ( size < 0 ) return; if ( from == BEGINNING ) - clip()->setEnd( clip()->getBegin() + size ); + { +// clip()->setEnd( clip()->getBegin() + size ); + tracksView()->getRenderer()->resizeClip( clip(), clip()->getBegin(), clip()->getBegin() + size, boundingRect().x(), + trackNumber(), MainWorkflow::VideoTrack ); + } else { qint64 oldLength = clip()->getLength(); @@ -115,7 +122,9 @@ void AbstractGraphicsMediaItem::resize( qint64 size, From from ) qWarning( "Warning: resizing a region with a size below 0" ); size += clip()->getEnd() - size; } - clip()->setBegin( qMax( clip()->getEnd() - size, (qint64)0 ) ); +// clip()->setBegin( qMax( clip()->getEnd() - size, (qint64)0 ) ); + tracksView()->getRenderer()->resizeClip( clip(), qMax( clip()->getEnd() - size, (qint64)0 ), clip()->getEnd(), + startPos() + ( oldLength - size ), trackNumber(), MainWorkflow::VideoTrack ); setStartPos( startPos() + ( oldLength - size ) ); } diff --git a/src/GUI/TracksView.cpp b/src/GUI/TracksView.cpp index f8802ae4..60e2f144 100644 --- a/src/GUI/TracksView.cpp +++ b/src/GUI/TracksView.cpp @@ -569,6 +569,7 @@ void TracksView::mousePressEvent( QMouseEvent* event ) m_actionResize = true; m_actionResizeStart = mapToScene( event->pos() ).x(); m_actionResizeBase = item->clip()->getLength(); + m_actionResizeOldBegin = item->clip()->getBegin(); m_actionItem = item; } else if ( item->moveable() ) @@ -627,6 +628,12 @@ void TracksView::mouseReleaseEvent( QMouseEvent* event ) } else if ( m_actionResize ) { + Clip* clip = m_actionItem->clip(); + //This is a "pointless action". The resize already occured. However, by doing this + //we can have an undo action. + Commands::trigger( new Commands::MainWorkflow::ResizeClip( m_renderer, clip->getUuid(), clip->getBegin(), + clip->getEnd(), m_actionResizeOldBegin, m_actionResizeOldBegin + m_actionResizeBase, + m_actionItem->pos().x(), m_actionResizeStart, m_actionItem->trackNumber(), MainWorkflow::VideoTrack ) ); updateDuration(); } diff --git a/src/GUI/TracksView.h b/src/GUI/TracksView.h index 050af8b7..b58dbc14 100644 --- a/src/GUI/TracksView.h +++ b/src/GUI/TracksView.h @@ -61,6 +61,7 @@ public: void removeMediaItem( const QList& items ); void setTool( ToolButtons button ); ToolButtons tool() { return m_tool; } + WorkflowRenderer* getRenderer() { return m_renderer; } public slots: void clear(); @@ -112,6 +113,7 @@ private: bool m_actionResize; qint64 m_actionResizeStart; qint64 m_actionResizeBase; + qint64 m_actionResizeOldBegin; AbstractGraphicsMediaItem::From m_actionResizeType; int m_actionRelativeX; AbstractGraphicsMediaItem* m_actionItem; diff --git a/src/Media/Clip.cpp b/src/Media/Clip.cpp index b27c6feb..d878522d 100644 --- a/src/Media/Clip.cpp +++ b/src/Media/Clip.cpp @@ -184,6 +184,8 @@ void Clip::setEnd( qint64 end ) void Clip::setBoundaries( qint64 newBegin, qint64 newEnd ) { Q_ASSERT( newBegin < newEnd ); + if ( newBegin == m_begin && m_end == newEnd ) + return ; m_begin = newBegin; m_end = newEnd; computeLength(); diff --git a/src/Renderer/WorkflowRenderer.cpp b/src/Renderer/WorkflowRenderer.cpp index b77f7abd..9767c6a7 100644 --- a/src/Renderer/WorkflowRenderer.cpp +++ b/src/Renderer/WorkflowRenderer.cpp @@ -312,16 +312,25 @@ void WorkflowRenderer::unsplit( Clip* origin, Clip* splitted, uint32_t trackI } } -void WorkflowRenderer::resizeClip( Clip* clip, qint64 newBegin, qint64 newEnd ) +void WorkflowRenderer::resizeClip( Clip* clip, qint64 newBegin, qint64 newEnd, + qint64 newPos, uint32_t trackId, MainWorkflow::TrackType trackType, bool undoRedoAction /*= false*/ ) { if ( m_isRendering == true ) { - Action::Generic* act = new Action::ResizeClip( clip, newBegin, newEnd ); + Action::Generic* act = new Action::ResizeClip( clip, newBegin, newEnd ); + Action::Generic* act2 = new Action::MoveClip( m_mainWorkflow, clip->getUuid(), trackId, trackId, newPos, trackType, undoRedoAction ); QMutexLocker lock( m_actionsMutex ); m_actions.addAction( act ); + m_actions.addAction( act2 ); } else + { + if ( newBegin != clip->getBegin() ) + { + m_mainWorkflow->moveClip( clip->getUuid(), trackId, trackId, newPos, trackType, undoRedoAction ); + } clip->setBoundaries( newBegin, newEnd ); + } } ///////////////////////////////////////////////////////////////////// diff --git a/src/Renderer/WorkflowRenderer.h b/src/Renderer/WorkflowRenderer.h index 882ba950..9293e4a1 100644 --- a/src/Renderer/WorkflowRenderer.h +++ b/src/Renderer/WorkflowRenderer.h @@ -53,7 +53,12 @@ class WorkflowRenderer : public GenericRenderer void removeClip( const QUuid& uuid, uint32_t trackId, MainWorkflow::TrackType trackType ); Clip* split( Clip* toSplit, uint32_t trackId, qint64 newClipPos, qint64 newClipBegin, MainWorkflow::TrackType trackType ); void unsplit( Clip* origin, Clip* splitted, uint32_t trackId, qint64 oldEnd, MainWorkflow::TrackType trackType ); - void resizeClip( Clip* clip, qint64 newBegin, qint64 newEnd ); + /** + * \param undoRedoAction: if true, the potential move resulting from the resize will be emmited to the GUI. + * if this is not an undo redo action, the GUI is already aware of the move. + */ + void resizeClip( Clip* clip, qint64 newBegin, qint64 newEnd, qint64 newPos, + uint32_t trackId, MainWorkflow::TrackType trackType, bool undoRedoAction = false ); static void* lock( void* datas ); static void* lockAudio( void* datas ); diff --git a/src/Workflow/MainWorkflow.h b/src/Workflow/MainWorkflow.h index 11b3c217..8dc552a8 100644 --- a/src/Workflow/MainWorkflow.h +++ b/src/Workflow/MainWorkflow.h @@ -99,6 +99,7 @@ class MainWorkflow : public QObject, public Singleton void previousFrame(); Clip* removeClip( const QUuid& uuid, unsigned int trackId, MainWorkflow::TrackType trackType ); + void moveClip( const QUuid& uuid, unsigned int oldTrack, unsigned int newTrack, qint64 pos, MainWorkflow::TrackType trackType, bool undoRedoCommand = false ); -- GitLab