ardour
stateful_diff_command.cc
Go to the documentation of this file.
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 
21 #include "pbd/property_list.h"
22 #include "pbd/demangle.h"
23 #include "i18n.h"
24 
25 using namespace std;
26 using namespace PBD;
27 
34  : _object (s)
35  , _changes (0)
36 {
38 
39  /* if the stateful object that this command refers to goes away,
40  be sure to notify owners of this command.
41  */
42 
43  s->DropReferences.connect_same_thread (*this, boost::bind (&Destructible::drop_references, this));
44 }
45 
47  : _object (s)
48  , _changes (0)
49 {
50  const XMLNodeList& children (n.children());
51 
52  for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
53  if ((*i)->name() == X_("Changes")) {
54  _changes = s->property_factory (**i);
55  }
56  }
57 
58  assert (_changes != 0);
59 
60  /* if the stateful object that this command refers to goes away,
61  be sure to notify owners of this command.
62  */
63 
64  s->DropReferences.connect_same_thread (*this, boost::bind (&Destructible::drop_references, this));
65 }
66 
68 {
69  drop_references ();
70 
71  delete _changes;
72 }
73 
74 void
76 {
78 
79  if (s) {
80  s->apply_changes (*_changes);
81  }
82 }
83 
84 void
86 {
88 
89  if (s) {
91  p.invert ();
92  s->apply_changes (p);
93  }
94 }
95 
96 XMLNode&
98 {
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* changes = new XMLNode (X_("Changes"));
112 
113  _changes->get_changes_as_xml (changes);
114 
115  node->add_child_nocopy (*changes);
116 
117  return *node;
118 }
119 
120 bool
122 {
123  return _changes->empty();
124 }
PBD::Signal0< void > DropReferences
Definition: destructible.h:34
boost::weak_ptr< Stateful > _object
the object in question
virtual PropertyList * property_factory(const XMLNode &) const
Definition: stateful.cc:349
Definition: Beats.hpp:239
PropertyList * get_changes_as_properties(Command *) const
Definition: stateful.cc:192
const XMLNodeList & children(const std::string &str=std::string()) const
Definition: xml++.cc:329
std::list< XMLNode * > XMLNodeList
Definition: xml++.h:44
class LIBPBD_API StatefulDiffCommand
#define X_(Text)
Definition: i18n.h:13
PBD::PropertyList * _changes
property changes to execute this command
StatefulDiffCommand(boost::shared_ptr< StatefulDestructible >)
std::string demangled_name(T const &obj)
Definition: demangle.h:36
void get_changes_as_xml(XMLNode *)
void drop_references()
Definition: destructible.h:36
XMLProperty * add_property(const char *name, const std::string &value)
void add_child_nocopy(XMLNode &)
Definition: xml++.cc:357
Definition: xml++.h:95
Definition: debug.h:30