fix last commit
[ardour.git] / libs / ardour / region_command.cc
1 #include "pbd/convert.h"
2 #include "pbd/xml++.h"
3 #include "pbd/locale_guard.h"
4 #include "pbd/enumwriter.h"
5
6 #include "ardour/region.h"
7 #include "ardour/region_command.h"
8 #include "ardour/utils.h"
9
10 #include "i18n.h"
11
12 using namespace ARDOUR;
13 using namespace PBD;
14 using namespace std;
15
16 RegionCommand::RegionCommand (boost::shared_ptr<Region> r, const XMLNode& node)
17         : region (r)
18 {
19         if (set_state (node, 0)) {
20                 throw failed_constructor();
21         }
22 }
23
24 RegionCommand::RegionCommand (boost::shared_ptr<Region> r)
25         : region (r)
26 {
27 }
28
29 RegionCommand::RegionCommand (boost::shared_ptr<Region> r, Property prop, const std::string& target_value)
30         : region (r)
31 {
32         LocaleGuard lg ("POSIX");
33         string before;
34         char buf[128];
35
36         /* get current value as a string */
37         
38         switch (prop) {
39         case Name:
40                 before = r->name();
41                 break;
42         case PositionLockStyle:
43                 before = enum_2_string (r->positional_lock_style());
44                 break;
45         case Length:
46                 snprintf (buf, sizeof (buf), "%" PRId32, r->length());
47                 before = buf;
48                 break;
49         case Start:
50                 snprintf (buf, sizeof (buf), "%" PRId32, r->start());
51                 before = buf;
52                 break;
53         case Position:
54                 snprintf (buf, sizeof (buf), "%" PRId32, r->position());
55                 before = buf;
56                 break;
57         case PositionOnTop:
58                 snprintf (buf, sizeof (buf), "%" PRId32, r->position());
59                 before = buf;
60                 break;
61         case Layer:
62                 snprintf (buf, sizeof (buf), "%" PRId32, r->layer());
63                 before = buf;
64                 break;
65         case SyncPosition:
66                 snprintf (buf, sizeof (buf), "%" PRId32, r->sync_position());
67                 before = buf;
68                 break;
69         case Hidden:
70                 before = (r->hidden() ? "yes" : "no");
71                 break;
72         case Muted:
73                 before = (r->muted() ? "yes" : "no");
74                 break;
75         case Opaque:
76                 before = (r->opaque() ? "yes" : "no");
77                 break;
78         case Locked:
79                 before = (r->locked() ? "yes" : "no");
80                 break;
81         case PositionLocked:
82                 before = (r->position_locked() ? "yes" : "no");
83                 break;
84                 
85         /* audio */
86
87         case ScaleAmplitude:
88                 break;
89         case FadeInActive:
90                 break;
91         case FadeInShape:
92                 break;
93         case FadeInLength:
94                 break;
95         case FadeIn:
96                 break;
97         case FadeOutActive:
98                 break;
99         case FadeOutShape:
100                 break;
101         case FadeOutLength:
102                 break;
103         case FadeOut:
104                 break;
105         case EnvelopActive:
106                 break;
107         case DefaultEnvelope:
108                 break;
109                 
110         }
111
112         add_property_change (prop, before, target_value);
113 }
114
115 void
116 RegionCommand::_add_property_change (Property prop, const std::string& before, const std::string& after)
117 {
118         property_changes.push_back (PropertyTriple (prop, before, after));
119 }
120
121 void
122 RegionCommand::operator() ()
123 {
124         region->freeze ();
125         for (PropertyTriples::iterator i= property_changes.begin(); i != property_changes.end(); ++i) {
126                 do_property_change (i->property, i->after);
127         }
128         region->thaw ();
129 }
130
131 void
132 RegionCommand::undo ()
133 {
134         region->freeze ();
135         for (PropertyTriples::iterator i= property_changes.begin(); i != property_changes.end(); ++i) {
136                 do_property_change (i->property, i->before);
137         }
138         region->thaw ();
139 }
140
141 void
142 RegionCommand::do_property_change (Property prop, const std::string& value)
143 {
144         Region::PositionLockStyle pls;
145
146         switch (prop) {
147         case Name:
148                 region->set_name (value);
149                 break;
150         case PositionLockStyle:
151                 region->set_position_lock_style ((Region::PositionLockStyle) string_2_enum (value, pls));
152                 break;
153         case Length:
154                 region->set_length (atoll (value), this);
155                 break;
156         case Start:
157                 region->set_start (atoll (value), this);
158                 break;
159         case Position:
160                 region->set_position (atoll (value), this);
161                 break;
162         case PositionOnTop:
163                 region->set_position_on_top (atoll (value), this);
164                 break;
165         case Layer:
166                 region->set_layer (atoi (value));
167                 break;
168         case SyncPosition:
169                 region->set_sync_position (atoi (value));
170                 break;
171         case Hidden:
172                 region->set_hidden (string_is_affirmative (value));
173                 break;
174         case Muted:
175                 region->set_muted (string_is_affirmative (value));
176                 break;
177         case Opaque:
178                 region->set_opaque (string_is_affirmative (value));
179                 break;
180         case Locked:
181                 region->set_locked (string_is_affirmative (value));
182                 break;
183         case PositionLocked:
184                 region->set_position_locked (string_is_affirmative (value));
185                 break;
186
187         /* audio */
188
189         case ScaleAmplitude:
190                 break;
191         case FadeInActive:
192                 break;
193         case FadeInShape:
194                 break;
195         case FadeInLength:
196                 break;
197         case FadeIn:
198                 break;
199         case FadeOutActive:
200                 break;
201         case FadeOutShape:
202                 break;
203         case FadeOutLength:
204                 break;
205         case FadeOut:
206                 break;
207         case EnvelopActive:
208                 break;
209         case DefaultEnvelope:
210                 break;
211                 
212         }
213 }
214
215 XMLNode&
216 RegionCommand::get_state ()
217 {
218         XMLNode* node = new XMLNode (X_("RegionCommand"));
219         XMLNode* child;
220         
221         node->add_property (X_("region"), region->id().to_s());
222         
223         for (PropertyTriples::iterator i = property_changes.begin(); i != property_changes.end(); ++i) {
224
225                 child = new XMLNode (X_("Op"));
226
227                 child->add_property (X_("property"), enum_2_string (i->property));
228                 child->add_property (X_("before"), i->before);
229                 child->add_property (X_("after"), i->after);
230
231                 node->add_child_nocopy (*child);
232         }
233
234         return *node;
235 }
236
237 int
238 RegionCommand::set_state (const XMLNode& node, int /* version */)
239 {
240         const XMLNodeList& children (node.children());
241         Property property;
242         string before;
243         string after;
244         const XMLProperty* prop;
245         
246         for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
247
248                 if ((*i)->name() != X_("Op")) {
249                         continue;
250                 }
251
252                 if ((prop = (*i)->property (X_("property"))) == 0) {
253                         return -1;
254                 }
255
256                 property = (Property) string_2_enum (prop->value(), property);
257
258                 if ((prop = (*i)->property (X_("before"))) == 0) {
259                         return -1;
260                 }
261
262                 before = prop->value();
263
264                 if ((prop = (*i)->property (X_("after"))) == 0) {
265                         return -1;
266                 }
267
268                 after = prop->value();
269
270                 add_property_change (property, before, after);
271         }
272
273         return 0;
274 }