X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fpbd%2Fstateful_diff_command.cc;h=e3a65ffc12c69f5551c5d10fc9d7353ffd199056;hb=c4fcb12d128857a0eaab7d2093d38fdf4cc641cc;hp=0468ac3e8a21f47344ed6acfa4405ea59e896d08;hpb=50dd880d7e75b49e7c80c79f32165a756839651c;p=ardour.git diff --git a/libs/pbd/stateful_diff_command.cc b/libs/pbd/stateful_diff_command.cc index 0468ac3e8a..e3a65ffc12 100644 --- a/libs/pbd/stateful_diff_command.cc +++ b/libs/pbd/stateful_diff_command.cc @@ -1,5 +1,5 @@ /* - 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 @@ -17,52 +17,59 @@ */ -#include - #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 s) - : _object (s) - , _undo (new PropertyList) - , _redo (new PropertyList) +StatefulDiffCommand::StatefulDiffCommand (boost::shared_ptr 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 s, XMLNode const & n) +StatefulDiffCommand::StatefulDiffCommand (boost::shared_ptr 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); + + /* if the stateful object that this command refers to goes away, + be sure to notify owners of this command. + */ - assert (_undo != 0); - assert (_redo != 0); + s->DropReferences.connect_same_thread (*this, boost::bind (&Destructible::drop_references, this)); } StatefulDiffCommand::~StatefulDiffCommand () { - delete _undo; - delete _redo; + drop_references (); + + delete _changes; } void @@ -71,10 +78,7 @@ StatefulDiffCommand::operator() () boost::shared_ptr s (_object.lock()); if (s) { - PropertyChange changed = s->set_properties (*_redo); - if (!changed.empty()) { - s->PropertyChanged (changed); - } + s->apply_changes (*_changes); } } @@ -84,12 +88,9 @@ StatefulDiffCommand::undo () boost::shared_ptr s (_object.lock()); if (s) { - std::cerr << "Undoing a stateful diff command\n"; - PropertyChange changed = s->set_properties (*_undo); - if (!changed.empty()) { - std::cerr << "Sending changed\n"; - s->PropertyChanged (changed); - } + PropertyList p = *_changes; + p.invert (); + s->apply_changes (p); } } @@ -105,17 +106,20 @@ StatefulDiffCommand::get_state () 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(); +}