r268@gwythaint (orig r808): fugalh | 2006-08-12 16:31:45 -0600
[ardour.git] / libs / ardour / session_command.cc
1 #include <ardour/session.h>
2 #include <ardour/route.h>
3 #include <pbd/memento_command.h>
4 #include <ardour/diskstream.h>
5 #include <ardour/playlist.h>
6 #include <ardour/tempo.h>
7 #include <ardour/audiosource.h>
8 #include <ardour/audioregion.h>
9 #include <pbd/error.h>
10 using namespace PBD;
11 #include "i18n.h"
12
13
14 namespace ARDOUR {
15
16 static map<PBD::ID, Stateful*> registry;
17
18 void Session::register_with_memento_command_factory(PBD::ID id, Stateful *ptr)
19 {
20     registry[id] = ptr;
21 }
22     
23 Command *Session::memento_command_factory(XMLNode *n)
24 {
25     PBD::ID id;
26     XMLNode *before = 0, *after = 0;
27     XMLNode *child;
28
29     /* get id */
30     id = PBD::ID(n->property("obj_id")->value());
31
32     /* get before/after */
33     if (n->name() == "MementoCommand")
34     {
35         before = new XMLNode(*n->children().front());
36         after = new XMLNode(*n->children().back());
37         child = before;
38     } else if (n->name() == "MementoUndoCommand")
39     {
40         before = new XMLNode(*n->children().front());
41         child = before;
42     }
43     else if (n->name() == "MementoRedoCommand")
44     {
45         after = new XMLNode(*n->children().front());
46         child = after;
47     }
48
49     if (!child)
50     {
51         error << _("Tried to reconstitute a MementoCommand with no contents, failing. id=") << id.to_s() << endmsg;
52         return 0;
53     }
54
55
56     /* create command */
57     string obj_T = n->children().front()->name();
58     if (obj_T == "AudioRegion" || obj_T == "Region")
59     {
60         if (audio_regions.count(id))
61             return new MementoCommand<AudioRegion>(*audio_regions[id], before, after);
62     }
63     else if (obj_T == "AudioSource")
64     {
65         if (audio_sources.count(id))
66             return new MementoCommand<AudioSource>(*audio_sources[id], before, after);
67     }
68     else if (obj_T == "Location")
69         return new MementoCommand<Location>(*_locations.get_location_by_id(id), before, after);
70     else if (obj_T == "Locations")
71         return new MementoCommand<Locations>(_locations, before, after);
72     else if (obj_T == "TempoMap")
73         return new MementoCommand<TempoMap>(*_tempo_map, before, after);
74     else if (obj_T == "Playlist" || obj_T == "AudioPlaylist")
75     {
76         if (Playlist *pl = playlist_by_name(child->property("name")->value()))
77             return new MementoCommand<Playlist>(*pl, before, after);
78     }
79     else if (obj_T == "Route") // inlcudes AudioTrack
80         return new MementoCommand<Route>(*route_by_id(id), before, after);
81     else if (obj_T == "Curve")
82     {
83         if (curves.count(id))
84             return new MementoCommand<Curve>(*curves[id], before, after);
85     }
86     else if (obj_T == "AutomationList")
87     {
88         if (automation_lists.count(id))
89             return new MementoCommand<AutomationList>(*automation_lists[id], before, after);
90     }
91     // For Editor and AutomationLine which are off-limits here
92     else if (registry.count(id))
93         return new MementoCommand<Stateful>(*registry[id], before, after);
94
95     /* we failed */
96     error << _("could not reconstitute MementoCommand from XMLNode. id=") << id.to_s() << endmsg;
97     return 0;
98 }
99
100 // solo
101 Session::GlobalSoloStateCommand::GlobalSoloStateCommand(Session &sess, void *src)
102     : sess(sess), src(src)
103 {
104     after = before = sess.get_global_route_boolean(&Route::soloed);
105 }
106 void Session::GlobalSoloStateCommand::mark()
107 {
108     after = sess.get_global_route_boolean(&Route::soloed);
109 }
110 void Session::GlobalSoloStateCommand::operator()()
111 {
112     sess.set_global_solo(after, src);
113 }
114 void Session::GlobalSoloStateCommand::undo()
115 {
116     sess.set_global_solo(before, src);
117 }
118 XMLNode &Session::GlobalSoloStateCommand::get_state()
119 {
120     XMLNode *node = new XMLNode("GlobalSoloStateCommand");
121     return *node;
122 }
123
124 // mute
125 Session::GlobalMuteStateCommand::GlobalMuteStateCommand(Session &sess, void *src)
126     : sess(sess), src(src)
127 {
128     after = before = sess.get_global_route_boolean(&Route::muted);
129 }
130 void Session::GlobalMuteStateCommand::mark()
131 {
132     after = sess.get_global_route_boolean(&Route::muted);
133 }
134 void Session::GlobalMuteStateCommand::operator()()
135 {
136     sess.set_global_mute(after, src);
137 }
138 void Session::GlobalMuteStateCommand::undo()
139 {
140     sess.set_global_mute(before, src);
141 }
142 XMLNode &Session::GlobalMuteStateCommand::get_state()
143 {
144     XMLNode *node = new XMLNode("GlobalMuteStateCommand");
145     return *node;
146 }
147
148 // record enable
149 Session::GlobalRecordEnableStateCommand::GlobalRecordEnableStateCommand(Session &sess, void *src) 
150     : sess(sess), src(src)
151 {
152     after = before = sess.get_global_route_boolean(&Route::record_enabled);
153 }
154 void Session::GlobalRecordEnableStateCommand::mark()
155 {
156     after = sess.get_global_route_boolean(&Route::record_enabled);
157 }
158 void Session::GlobalRecordEnableStateCommand::operator()()
159 {
160     sess.set_global_record_enable(after, src);
161 }
162 void Session::GlobalRecordEnableStateCommand::undo()
163 {
164     sess.set_global_record_enable(before, src);
165 }
166 XMLNode &Session::GlobalRecordEnableStateCommand::get_state()
167 {
168     XMLNode *node = new XMLNode("GlobalRecordEnableStateCommand");
169     return *node;
170 }
171
172 // metering
173 Session::GlobalMeteringStateCommand::GlobalMeteringStateCommand(Session &sess, void *src) 
174     : sess(sess), src(src)
175 {
176     after = before = sess.get_global_route_metering();
177 }
178 void Session::GlobalMeteringStateCommand::mark()
179 {
180     after = sess.get_global_route_metering();
181 }
182 void Session::GlobalMeteringStateCommand::operator()()
183 {
184     sess.set_global_route_metering(after, src);
185 }
186 void Session::GlobalMeteringStateCommand::undo()
187 {
188     sess.set_global_route_metering(before, src);
189 }
190 XMLNode &Session::GlobalMeteringStateCommand::get_state()
191 {
192     XMLNode *node = new XMLNode("GlobalMeteringStateCommand");
193     return *node;
194 }
195
196 } // namespace ARDOUR