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