From 074d58fc6f97c225e804d32b5d2b8f09e4d512da Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 19 Jan 2011 17:38:46 +0000 Subject: [PATCH] Fix undo nesting. git-svn-id: svn://localhost/ardour2/branches/3.0@8538 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/ardour/ardour/session.h | 11 +++++--- libs/ardour/session.cc | 2 ++ libs/ardour/session_state.cc | 49 ++++++++++++++++++++++++------------ libs/pbd/pbd/undo.h | 4 +-- 4 files changed, 43 insertions(+), 23 deletions(-) diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index e5032ad8c2..2dc2650be9 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -669,8 +669,8 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi void commit_reversible_command (Command* cmd = 0); void add_command (Command *const cmd) { - assert(!_current_trans.empty ()); - _current_trans.top()->add_command (cmd); + assert (_current_trans); + _current_trans->add_command (cmd); } void add_commands (std::vector const & cmds); @@ -1336,8 +1336,11 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi void reverse_track_buffers (); - UndoHistory _history; - std::stack _current_trans; + UndoHistory _history; + /** current undo transaction, or 0 */ + UndoTransaction* _current_trans; + /** number of times that begin_reversible_command has been called without commit_reversible_command */ + int _current_trans_depth; void jack_timebase_callback (jack_transport_state_t, pframes_t, jack_position_t*, int); int jack_sync_callback (jack_transport_state_t, jack_position_t*); diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 72163155a5..4d31c20456 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -151,6 +151,8 @@ Session::Session (AudioEngine &eng, , _total_free_4k_blocks (0) , _bundles (new BundleList) , _bundle_xml_node (0) + , _current_trans (0) + , _current_trans_depth (0) , _click_io ((IO*) 0) , click_data (0) , click_emphasis_data (0) diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index 6fdaf749ab..e7ccb02c7b 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -2362,38 +2362,55 @@ Session::add_commands (vector const & cmds) } void -Session::begin_reversible_command(const string& name) +Session::begin_reversible_command (const string& name) { - UndoTransaction* trans = new UndoTransaction(); - trans->set_name(name); - - if (!_current_trans.empty()) { - _current_trans.top()->add_command (trans); + /* If nested begin/commit pairs are used, we create just one UndoTransaction + to hold all the commands that are committed. This keeps the order of + commands correct in the history. + */ + + if (_current_trans == 0) { + /* start a new transaction */ + assert (_current_trans_depth == 0); + _current_trans = new UndoTransaction(); + _current_trans->set_name (name); } else { - _current_trans.push(trans); + /* use the existing transaction */ + ++_current_trans_depth; } } void -Session::commit_reversible_command(Command *cmd) +Session::commit_reversible_command (Command *cmd) { - assert(!_current_trans.empty()); + assert (_current_trans); + assert (_current_trans_depth > 0); + struct timeval now; if (cmd) { - _current_trans.top()->add_command(cmd); + _current_trans->add_command (cmd); } - if (_current_trans.top()->empty()) { - _current_trans.pop(); + --_current_trans_depth; + + if (_current_trans_depth > 0) { + /* the transaction we're committing is not the top-level one */ return; } - gettimeofday(&now, 0); - _current_trans.top()->set_timestamp(now); + if (_current_trans->empty()) { + /* no commands were added to the transaction, so just get rid of it */ + delete _current_trans; + _current_trans = 0; + return; + } - _history.add(_current_trans.top()); - _current_trans.pop(); + gettimeofday (&now, 0); + _current_trans->set_timestamp (now); + + _history.add (_current_trans); + _current_trans = 0; } static bool diff --git a/libs/pbd/pbd/undo.h b/libs/pbd/pbd/undo.h index fb5152c293..11ff2bf321 100644 --- a/libs/pbd/pbd/undo.h +++ b/libs/pbd/pbd/undo.h @@ -37,6 +37,7 @@ class UndoTransaction : public Command UndoTransaction (); UndoTransaction (const UndoTransaction&); UndoTransaction& operator= (const UndoTransaction&); + ~UndoTransaction (); void clear (); bool empty() const; @@ -66,9 +67,6 @@ class UndoTransaction : public Command friend void command_death (UndoTransaction*, Command *); - friend class UndoHistory; - - ~UndoTransaction (); void about_to_explicitly_delete (); };