- 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();
- }
- }
+ return &m_undoables[undoable];
+}
+void release( Undoable* undoable ){
+ ASSERT_NOTNULL( undoable );
+
+ 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();
+ }
+}