revert incorrect include path changes and removal of export macros for two libardour...
[ardour.git] / libs / pbd / undo.cc
index 1a2574ae28ab915abb68564ba617f7eb1a39877a..42f7d574ea4030f44f486215901dedba64c0af25 100644 (file)
@@ -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->GoingAway.connect (*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;
@@ -186,7 +200,7 @@ UndoHistory::add (UndoTransaction* const ut)
 {
        uint32_t current_depth = UndoList.size();
 
-       ut->GoingAway.connect (*this, boost::bind (&UndoHistory::remove, this, ut));
+       ut->DropReferences.connect_same_thread (*this, boost::bind (&UndoHistory::remove, this, ut));
 
        /* if the current undo history is larger than or equal to the currently
           requested depth, then pop off at least 1 element to make space
@@ -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<UndoTransaction*>::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<UndoTransaction*>::iterator i = UndoList.begin(); i != UndoList.end(); ++i) {
+                delete *i;
+        }
        UndoList.clear ();
        _clearing = false;