Fix undo nesting.

git-svn-id: svn://localhost/ardour2/branches/3.0@8538 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Carl Hetherington 2011-01-19 17:38:46 +00:00
parent 5535b994d3
commit 074d58fc6f
4 changed files with 43 additions and 23 deletions

View File

@ -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<Command*> const & cmds);
@ -1336,8 +1336,11 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
void reverse_track_buffers ();
UndoHistory _history;
std::stack<UndoTransaction*> _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*);

View File

@ -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)

View File

@ -2362,38 +2362,55 @@ Session::add_commands (vector<Command*> 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

View File

@ -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 ();
};