- m_undoables.erase( undoable );
-}
-void setLevels( std::size_t levels ){
- if ( levels > MAX_UNDO_LEVELS() ) {
- levels = MAX_UNDO_LEVELS();
- }
-
- while ( m_undo_stack.size() > levels )
- {
- m_undo_stack.pop_front();
- }
- m_undo_levels = levels;
-}
-std::size_t getLevels() const {
- return m_undo_levels;
-}
-std::size_t size() const {
- return m_undo_stack.size();
-}
-void startUndo(){
- m_undo_stack.start( "unnamedCommand" );
- mark_undoables( &m_undo_stack );
-}
-bool finishUndo( const char* command ){
- bool changed = m_undo_stack.finish( command );
- mark_undoables( 0 );
- return changed;
-}
-void startRedo(){
- m_redo_stack.start( "unnamedCommand" );
- mark_undoables( &m_redo_stack );
-}
-bool finishRedo( const char* command ){
- bool changed = m_redo_stack.finish( command );
- mark_undoables( 0 );
- return changed;
-}
-void start(){
- m_redo_stack.clear();
- if ( m_undo_stack.size() == m_undo_levels ) {
- m_undo_stack.pop_front();
- }
- startUndo();
- trackersBegin();
-}
-void finish( const char* command ){
- if ( finishUndo( command ) ) {
- globalOutputStream() << command << '\n';
- }
-}
-void undo(){
- if ( m_undo_stack.empty() ) {
- globalOutputStream() << "Undo: no undo available\n";
- }
- else
- {
- Operation* operation = m_undo_stack.back();
- globalOutputStream() << "Undo: " << operation->m_command.c_str() << "\n";
-
- startRedo();
- trackersUndo();
- operation->m_snapshot.restore();
- finishRedo( operation->m_command.c_str() );
- m_undo_stack.pop_back();
- }
-}
-void redo(){
- if ( m_redo_stack.empty() ) {
- globalOutputStream() << "Redo: no redo available\n";
- }
- else
- {
- Operation* operation = m_redo_stack.back();
- globalOutputStream() << "Redo: " << operation->m_command.c_str() << "\n";
-
- startUndo();
- trackersRedo();
- operation->m_snapshot.restore();
- finishUndo( operation->m_command.c_str() );
- m_redo_stack.pop_back();
- }
-}
-void clear(){
- mark_undoables( 0 );
- m_undo_stack.clear();
- m_redo_stack.clear();
- trackersClear();
-}
-void trackerAttach( UndoTracker& tracker ){
- ASSERT_MESSAGE( m_trackers.find( &tracker ) == m_trackers.end(), "undo tracker already attached" );
- m_trackers.insert( &tracker );
-}
-void trackerDetach( UndoTracker& tracker ){
- ASSERT_MESSAGE( m_trackers.find( &tracker ) != m_trackers.end(), "undo tracker cannot be detached" );
- m_trackers.erase( &tracker );
-}
-void trackersClear() const {
- for ( Trackers::const_iterator i = m_trackers.begin(); i != m_trackers.end(); ++i )
- {
- ( *i )->clear();
- }
-}
-void trackersBegin() const {
- for ( Trackers::const_iterator i = m_trackers.begin(); i != m_trackers.end(); ++i )
- {
- ( *i )->begin();
- }
-}
-void trackersUndo() const {
- for ( Trackers::const_iterator i = m_trackers.begin(); i != m_trackers.end(); ++i )
- {
- ( *i )->undo();
- }
-}
-void trackersRedo() const {
- for ( Trackers::const_iterator i = m_trackers.begin(); i != m_trackers.end(); ++i )
- {
- ( *i )->redo();
- }
-}
-};