summaryrefslogtreecommitdiff
path: root/libs/pbd/pbd
diff options
context:
space:
mode:
authorCarl Hetherington <carl@carlh.net>2010-08-26 01:44:11 +0000
committerCarl Hetherington <carl@carlh.net>2010-08-26 01:44:11 +0000
commitc243a02c998f585295f2179657673e2cf0fa4428 (patch)
tree1a18ca901b5f7fb1270938e2fb62f7e2636400ef /libs/pbd/pbd
parentdf2fd9491904aba95e08e1e26552be609530ee83 (diff)
Fix crossfade undo using the stateful diff system. Fixes #3257.
git-svn-id: svn://localhost/ardour2/branches/3.0@7694 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/pbd/pbd')
-rw-r--r--libs/pbd/pbd/command.h4
-rw-r--r--libs/pbd/pbd/property_basics.h2
-rw-r--r--libs/pbd/pbd/sequence_property.h31
-rw-r--r--libs/pbd/pbd/stateful.h2
-rw-r--r--libs/pbd/pbd/stateful_diff_command.h2
5 files changed, 30 insertions, 11 deletions
diff --git a/libs/pbd/pbd/command.h b/libs/pbd/pbd/command.h
index c6c3c8d3fd..db4d2bbd81 100644
--- a/libs/pbd/pbd/command.h
+++ b/libs/pbd/pbd/command.h
@@ -43,6 +43,10 @@ public:
virtual XMLNode &get_state();
virtual int set_state(const XMLNode&, int /*version*/) { /* noop */ return 0; }
+ virtual bool empty () const {
+ return false;
+ }
+
protected:
Command() {}
Command(const std::string& name) : _name(name) {}
diff --git a/libs/pbd/pbd/property_basics.h b/libs/pbd/pbd/property_basics.h
index cfae36df20..145e84abfc 100644
--- a/libs/pbd/pbd/property_basics.h
+++ b/libs/pbd/pbd/property_basics.h
@@ -103,7 +103,7 @@ public:
virtual void get_changes_as_properties (PropertyList& changes, Command *) const = 0;
/** Collect StatefulDiffCommands for changes to anything that we own */
- virtual void rdiff (std::vector<StatefulDiffCommand*> &) const {}
+ virtual void rdiff (std::vector<Command*> &) const {}
/** Look in an XML node written by get_changes_as_xml and, if XML from this property
* is found, create a property with the changes from the XML.
diff --git a/libs/pbd/pbd/sequence_property.h b/libs/pbd/pbd/sequence_property.h
index 5b37d7a0fc..4b494d4a8d 100644
--- a/libs/pbd/pbd/sequence_property.h
+++ b/libs/pbd/pbd/sequence_property.h
@@ -31,6 +31,7 @@
#include "pbd/id.h"
#include "pbd/property_basics.h"
#include "pbd/property_list.h"
+#include "pbd/stateful_diff_command.h"
namespace PBD {
@@ -80,8 +81,6 @@ class SequenceProperty : public PropertyBase
SequenceProperty (PropertyID id, const boost::function<void(const ChangeRecord&)>& update)
: PropertyBase (id), _update_callback (update) {}
- virtual typename Container::value_type lookup_id (const PBD::ID&) const = 0;
-
void invert () {
_changes.removed.swap (_changes.added);
}
@@ -97,18 +96,25 @@ class SequenceProperty : public PropertyBase
for (typename ChangeContainer::iterator i = _changes.added.begin(); i != _changes.added.end(); ++i) {
XMLNode* add_node = new XMLNode ("Add");
child->add_child_nocopy (*add_node);
- add_node->add_property ("id", (*i)->id().to_s());
+ get_content_as_xml (*i, *add_node);
}
}
if (!_changes.removed.empty()) {
for (typename ChangeContainer::iterator i = _changes.removed.begin(); i != _changes.removed.end(); ++i) {
XMLNode* remove_node = new XMLNode ("Remove");
child->add_child_nocopy (*remove_node);
- remove_node->add_property ("id", (*i)->id().to_s());
+ get_content_as_xml (*i, *remove_node);
}
}
}
+ /** Get a representation of one of our items as XML. The representation must be sufficient to
+ * restore the item's state later; an ID is ok if someone else is storing the item state,
+ * otherwise it needs to be the full state. The supplied node is an <Add> or <Remove>
+ * which this method can either add properties or children to.
+ */
+ virtual void get_content_as_xml (typename ChangeContainer::value_type, XMLNode &) const = 0;
+
bool set_value (XMLNode const &) {
/* XXX: not used, but probably should be */
assert (false);
@@ -191,11 +197,10 @@ class SequenceProperty : public PropertyBase
XMLNodeList const & grandchildren = (*i)->children ();
for (XMLNodeList::const_iterator j = grandchildren.begin(); j != grandchildren.end(); ++j) {
- XMLProperty const * prop = (*j)->property ("id");
- assert (prop);
- PBD::ID id (prop->value ());
- typename Container::value_type v = lookup_id (id);
+
+ typename Container::value_type v = get_content_from_xml (**j);
assert (v);
+
if ((*j)->name() == "Add") {
p->_changes.added.insert (v);
} else if ((*j)->name() == "Remove") {
@@ -206,13 +211,16 @@ class SequenceProperty : public PropertyBase
return p;
}
+ /** Given an <Add> or <Remove> node as passed into get_content_to_xml, obtain an item */
+ virtual typename Container::value_type get_content_from_xml (XMLNode const & node) const = 0;
+
void clear_owned_changes () {
for (typename Container::iterator i = begin(); i != end(); ++i) {
(*i)->clear_changes ();
}
}
- void rdiff (std::vector<StatefulDiffCommand*>& cmds) const {
+ void rdiff (std::vector<Command*>& cmds) const {
for (typename Container::const_iterator i = begin(); i != end(); ++i) {
if ((*i)->changed ()) {
StatefulDiffCommand* sdc = new StatefulDiffCommand (*i);
@@ -255,6 +263,11 @@ class SequenceProperty : public PropertyBase
return _val.erase (f, l);
}
+ void remove (const typename Container::value_type& v) {
+ _changes.remove (v);
+ _val.remove (v);
+ }
+
void push_back (const typename Container::value_type& v) {
_changes.add (v);
_val.push_back (v);
diff --git a/libs/pbd/pbd/stateful.h b/libs/pbd/pbd/stateful.h
index 5c1f079bc6..735ffbdc4a 100644
--- a/libs/pbd/pbd/stateful.h
+++ b/libs/pbd/pbd/stateful.h
@@ -70,7 +70,7 @@ class Stateful {
void clear_changes ();
virtual void clear_owned_changes ();
PropertyList* get_changes_as_properties (Command *) const;
- virtual void rdiff (std::vector<StatefulDiffCommand*> &) const;
+ virtual void rdiff (std::vector<Command*> &) const;
bool changed() const;
/* create a property list from an XMLNode
diff --git a/libs/pbd/pbd/stateful_diff_command.h b/libs/pbd/pbd/stateful_diff_command.h
index 2d5c234d76..2a213d7a17 100644
--- a/libs/pbd/pbd/stateful_diff_command.h
+++ b/libs/pbd/pbd/stateful_diff_command.h
@@ -45,6 +45,8 @@ public:
XMLNode& get_state ();
+ bool empty () const;
+
private:
boost::weak_ptr<Stateful> _object; ///< the object in question
PBD::PropertyList* _changes; ///< property changes to execute this command