/*
- 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)
- , _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
boost::shared_ptr<Stateful> s (_object.lock());
if (s) {
- s->set_properties (*_redo);
+ s->apply_changes (*_changes);
}
}
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);
}
}
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* undo = new XMLNode (X_("Undo"));
- XMLNode* redo = new XMLNode (X_("Do"));
+ _changes->get_changes_as_xml (changes);
- _undo->add_history_state (undo);
- _redo->add_history_state (redo);
-
- node->add_child_nocopy (*undo);
- node->add_child_nocopy (*redo);
+ node->add_child_nocopy (*changes);
return *node;
}
+
+bool
+StatefulDiffCommand::empty () const
+{
+ return _changes->empty();
+}