tweak transport bar spacing
[ardour.git] / libs / pbd / stateful_diff_command.cc
index 635fe4829ab0f5e9d3f9abecb1ef90c62c8c39a1..0f456d2d6e6ac9f042501dd521968bc8f5609fc7 100644 (file)
@@ -28,41 +28,49 @@ using namespace std;
 using namespace PBD;
 
 /** Create a new StatefulDiffCommand by examining the changes made to a Stateful
- *  since the last time that clear_history was called on it.
+ *  since the last time that clear_changes was called on it.
  *  @param s Stateful object.
  */
 
-StatefulDiffCommand::StatefulDiffCommand (boost::shared_ptr<Stateful> s)
-       : _object (s)
-        , _undo (new PropertyList)
-        , _redo (new PropertyList)
+StatefulDiffCommand::StatefulDiffCommand (boost::shared_ptr<StatefulDestructible> s)
+        : _object (s)
+        , _changes (0)
 {
-        s->diff (*_undo, *_redo);
+       _changes = s->get_changes_as_properties (this);
+
+        /* if the stateful object that this command refers to goes away,
+           be sure to notify owners of this command.
+        */
+
+        s->DropReferences.connect_same_thread (*this, boost::bind (&Destructible::drop_references, this));
 }
 
-StatefulDiffCommand::StatefulDiffCommand (boost::shared_ptr<Stateful> s, XMLNode const & n)
+StatefulDiffCommand::StatefulDiffCommand (boost::shared_ptr<StatefulDestructible> s, XMLNode const & n)
        : _object (s)
-        , _undo (0)
-        , _redo (0)
+        , _changes (0)
 {
         const XMLNodeList& children (n.children());
 
         for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
-                if ((*i)->name() == X_("Undo")) {
-                        _undo = s->property_factory (**i);
-                } else if ((*i)->name() == X_("Do")) {
-                        _redo = s->property_factory (**i);
+                if ((*i)->name() == X_("Changes")) {
+                        _changes = s->property_factory (**i);
                 }
-        }
+       }
+
+        assert (_changes != 0);
 
-        assert (_undo != 0);
-        assert (_redo != 0);
+        /* if the stateful object that this command refers to goes away,
+           be sure to notify owners of this command.
+        */
+
+        s->DropReferences.connect_same_thread (*this, boost::bind (&Destructible::drop_references, this));
 }
 
 StatefulDiffCommand::~StatefulDiffCommand ()
 {
-        delete _undo;
-        delete _redo;
+        drop_references ();
+
+        delete _changes;
 }
 
 void
@@ -71,7 +79,7 @@ StatefulDiffCommand::operator() ()
        boost::shared_ptr<Stateful> s (_object.lock());
 
        if (s) {
-                s->set_properties (*_redo);
+                s->apply_changes (*_changes);
        }
 }
 
@@ -81,8 +89,9 @@ StatefulDiffCommand::undo ()
        boost::shared_ptr<Stateful> s (_object.lock());
 
        if (s) {
-                std::cerr << "Undoing a stateful diff command\n";
-                s->set_properties (*_undo);
+               PropertyList p = *_changes;
+               p.invert ();
+                s->apply_changes (p);
        }
 }
 
@@ -101,14 +110,17 @@ StatefulDiffCommand::get_state ()
        node->add_property ("obj-id", s->id().to_s());
        node->add_property ("type-name", demangled_name (*s.get()));
 
-        XMLNode* undo = new XMLNode (X_("Undo"));
-        XMLNode* redo = new XMLNode (X_("Do"));
+        XMLNode* changes = new XMLNode (X_("Changes"));
 
-        _undo->add_history_state (undo);
-        _redo->add_history_state (redo);
+        _changes->get_changes_as_xml (changes);
         
-        node->add_child_nocopy (*undo);
-        node->add_child_nocopy (*redo);
+        node->add_child_nocopy (*changes);
 
        return *node;
 }
+
+bool
+StatefulDiffCommand::empty () const
+{
+       return _changes->empty();
+}