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