X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fpbd%2Fundo.cc;h=42f7d574ea4030f44f486215901dedba64c0af25;hb=e3329000557015ce54691235769db8821e75666b;hp=c3594b16584cf10c6b56f57c7aae068d2678afb6;hpb=c83389b8ec5fef9553a401e6123b7e55702af9e2;p=ardour.git diff --git a/libs/pbd/undo.cc b/libs/pbd/undo.cc index c3594b1658..42f7d574ea 100644 --- a/libs/pbd/undo.cc +++ b/libs/pbd/undo.cc @@ -38,9 +38,9 @@ UndoTransaction::UndoTransaction () UndoTransaction::UndoTransaction (const UndoTransaction& rhs) : Command(rhs._name) - , PBD::ScopedConnectionList () , _clearing(false) { + _timestamp = rhs._timestamp; clear (); actions.insert(actions.end(),rhs.actions.begin(),rhs.actions.end()); } @@ -76,15 +76,15 @@ UndoTransaction::operator= (const UndoTransaction& rhs) } void -UndoTransaction::add_command (Command *const action) +UndoTransaction::add_command (Command *const cmd) { /* catch death of command (e.g. caused by death of object to which it refers. command_death() is a normal static function so there is no need to manage this connection. */ - action->DropReferences.connect_same_thread (*this, boost::bind (&command_death, this, action)); - actions.push_back (action); + cmd->DropReferences.connect_same_thread (*this, boost::bind (&command_death, this, cmd)); + actions.push_back (cmd); } void @@ -150,6 +150,20 @@ XMLNode &UndoTransaction::get_state() return *node; } +class UndoRedoSignaller { +public: + UndoRedoSignaller (UndoHistory& uh) + : _history (uh) { + _history.BeginUndoRedo(); + } + ~UndoRedoSignaller() { + _history.EndUndoRedo(); + } + +private: + UndoHistory& _history; +}; + UndoHistory::UndoHistory () { _clearing = false; @@ -231,14 +245,22 @@ UndoHistory::remove (UndoTransaction* const ut) void UndoHistory::undo (unsigned int n) { - while (n--) { - if (UndoList.size() == 0) { - return; + if (n == 0) { + return; + } + + { + UndoRedoSignaller exception_safe_signaller (*this); + + while (n--) { + if (UndoList.size() == 0) { + return; + } + UndoTransaction* ut = UndoList.back (); + UndoList.pop_back (); + ut->undo (); + RedoList.push_back (ut); } - UndoTransaction* ut = UndoList.back (); - UndoList.pop_back (); - ut->undo (); - RedoList.push_back (ut); } Changed (); /* EMIT SIGNAL */ @@ -247,14 +269,22 @@ UndoHistory::undo (unsigned int n) void UndoHistory::redo (unsigned int n) { - while (n--) { - if (RedoList.size() == 0) { - return; + if (n == 0) { + return; + } + + { + UndoRedoSignaller exception_safe_signaller (*this); + + while (n--) { + if (RedoList.size() == 0) { + return; + } + UndoTransaction* ut = RedoList.back (); + RedoList.pop_back (); + ut->redo (); + UndoList.push_back (ut); } - UndoTransaction* ut = RedoList.back (); - RedoList.pop_back (); - ut->redo (); - UndoList.push_back (ut); } Changed (); /* EMIT SIGNAL */ @@ -264,6 +294,9 @@ void UndoHistory::clear_redo () { _clearing = true; + for (std::list::iterator i = RedoList.begin(); i != RedoList.end(); ++i) { + delete *i; + } RedoList.clear (); _clearing = false; @@ -275,6 +308,9 @@ void UndoHistory::clear_undo () { _clearing = true; + for (std::list::iterator i = UndoList.begin(); i != UndoList.end(); ++i) { + delete *i; + } UndoList.clear (); _clearing = false;