No-op: rename a few variables and add/fix some comments.
[ardour.git] / libs / pbd / stateful_diff_command.cc
1 /*
2     Copyright (C) 2010 Paul Davis 
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #include <iostream>
21
22 #include "pbd/stateful_diff_command.h"
23 #include "pbd/property_list.h"
24 #include "pbd/demangle.h"
25 #include "i18n.h"
26
27 using namespace std;
28 using namespace PBD;
29
30 /** Create a new StatefulDiffCommand by examining the changes made to a Stateful
31  *  since the last time that clear_history was called on it.
32  *  @param s Stateful object.
33  */
34
35 StatefulDiffCommand::StatefulDiffCommand (boost::shared_ptr<Stateful> s)
36         : _object (s)
37         , _undo (new PropertyList)
38         , _redo (new PropertyList)
39 {
40         s->diff (*_undo, *_redo);
41 }
42
43 StatefulDiffCommand::StatefulDiffCommand (boost::shared_ptr<Stateful> s, XMLNode const & n)
44         : _object (s)
45         , _undo (0)
46         , _redo (0)
47 {
48         const XMLNodeList& children (n.children());
49
50         for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
51                 if ((*i)->name() == X_("Undo")) {
52                         _undo = s->property_factory (**i);
53                 } else if ((*i)->name() == X_("Do")) {
54                         _redo = s->property_factory (**i);
55                 }
56         }
57
58         assert (_undo != 0);
59         assert (_redo != 0);
60 }
61
62 StatefulDiffCommand::~StatefulDiffCommand ()
63 {
64         delete _undo;
65         delete _redo;
66 }
67
68 void
69 StatefulDiffCommand::operator() ()
70 {
71         boost::shared_ptr<Stateful> s (_object.lock());
72
73         if (s) {
74                 PropertyChange changed = s->set_properties (*_redo);
75                 if (!changed.empty()) {
76                         s->PropertyChanged (changed);
77                 }
78         }
79 }
80
81 void
82 StatefulDiffCommand::undo ()
83 {
84         boost::shared_ptr<Stateful> s (_object.lock());
85
86         if (s) {
87                 std::cerr << "Undoing a stateful diff command\n";
88                 PropertyChange changed = s->set_properties (*_undo);
89                 if (!changed.empty()) {
90                         std::cerr << "Sending changed\n";
91                         s->PropertyChanged (changed);
92                 }
93         }
94 }
95
96 XMLNode&
97 StatefulDiffCommand::get_state ()
98 {
99         boost::shared_ptr<Stateful> s (_object.lock());
100
101         if (!s) {
102                 /* XXX should we throw? */
103                 return * new XMLNode("");
104         }
105
106         XMLNode* node = new XMLNode (X_("StatefulDiffCommand"));
107
108         node->add_property ("obj-id", s->id().to_s());
109         node->add_property ("type-name", demangled_name (*s.get()));
110
111         XMLNode* undo = new XMLNode (X_("Undo"));
112         XMLNode* redo = new XMLNode (X_("Do"));
113
114         _undo->add_history_state (undo);
115         _redo->add_history_state (redo);
116         
117         node->add_child_nocopy (*undo);
118         node->add_child_nocopy (*redo);
119
120         return *node;
121 }