/*
- Copyright (C) 2010 Paul Davis
+ Copyright (C) 2010 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
*/
-#include <iostream>
-
#include "pbd/stateful_diff_command.h"
+#include "pbd/types_convert.h"
#include "pbd/property_list.h"
#include "pbd/demangle.h"
-#include "i18n.h"
+#include "pbd/i18n.h"
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)
- , _before (new PropertyList)
- , _after (new PropertyList)
+StatefulDiffCommand::StatefulDiffCommand (boost::shared_ptr<StatefulDestructible> s)
+ : _object (s)
+ , _changes (0)
{
- s->diff (*_before, *_after);
+ _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)
- , _before (0)
- , _after (0)
+ , _changes (0)
{
const XMLNodeList& children (n.children());
for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
- if ((*i)->name() == X_("Undo")) {
- _before = s->property_factory (**i);
- } else if ((*i)->name() == X_("Do")) {
- _after = s->property_factory (**i);
+ if ((*i)->name() == X_("Changes")) {
+ _changes = s->property_factory (**i);
}
- }
+ }
+
+ assert (_changes != 0);
+
+ /* if the stateful object that this command refers to goes away,
+ be sure to notify owners of this command.
+ */
- assert (_before != 0);
- assert (_after != 0);
+ s->DropReferences.connect_same_thread (*this, boost::bind (&Destructible::drop_references, this));
}
StatefulDiffCommand::~StatefulDiffCommand ()
{
- delete _before;
- delete _after;
+ drop_references ();
+
+ delete _changes;
}
void
boost::shared_ptr<Stateful> s (_object.lock());
if (s) {
- PropertyChange changed = s->set_properties (*_after);
- if (!changed.empty()) {
- s->PropertyChanged (changed);
- }
+ s->apply_changes (*_changes);
}
}
boost::shared_ptr<Stateful> s (_object.lock());
if (s) {
- std::cerr << "Undoing a stateful diff command\n";
- PropertyChange changed = s->set_properties (*_before);
- if (!changed.empty()) {
- std::cerr << "Sending changed\n";
- s->PropertyChanged (changed);
- }
+ PropertyList p = *_changes;
+ p.invert ();
+ s->apply_changes (p);
}
}
XMLNode* node = new XMLNode (X_("StatefulDiffCommand"));
- node->add_property ("obj-id", s->id().to_s());
- node->add_property ("type-name", demangled_name (*s.get()));
+ node->set_property ("obj-id", s->id());
+ node->set_property ("type-name", demangled_name (*s.get()));
+
+ XMLNode* changes = new XMLNode (X_("Changes"));
- XMLNode* before = new XMLNode (X_("Undo"));
- XMLNode* after = new XMLNode (X_("Do"));
+ _changes->get_changes_as_xml (changes);
- _before->add_history_state (before);
- _after->add_history_state (after);
-
- node->add_child_nocopy (*before);
- node->add_child_nocopy (*after);
+ node->add_child_nocopy (*changes);
return *node;
}
+
+bool
+StatefulDiffCommand::empty () const
+{
+ return _changes->empty();
+}