new automation state model, sort of working, but not really
[ardour.git] / libs / ardour / session_command.cc
index 9a43de55de17ee1f9c8a04ce5984a96e3ae539d8..1492136b887486e7ce3cf4ee11dcbf6ddc12751a 100644 (file)
@@ -1,7 +1,93 @@
 #include <ardour/session.h>
 #include <ardour/route.h>
+#include <pbd/memento_command.h>
+#include <ardour/diskstream.h>
+#include <ardour/playlist.h>
+#include <ardour/tempo.h>
+#include <ardour/audiosource.h>
+#include <ardour/audioregion.h>
+#include <pbd/error.h>
+#include <pbd/statefuldestructible.h>
+
+using namespace PBD;
+
+#include "i18n.h"
 
 namespace ARDOUR {
+
+void Session::register_with_memento_command_factory(PBD::ID id, PBD::StatefulThingWithGoingAway *ptr)
+{
+    registry[id] = ptr;
+}
+    
+Command *Session::memento_command_factory(XMLNode *n)
+{
+    PBD::ID id;
+    XMLNode *before = 0, *after = 0;
+    XMLNode *child;
+
+    /* get id */
+    id = PBD::ID(n->property("obj_id")->value());
+
+    /* get before/after */
+
+    if (n->name() == "MementoCommand") {
+           before = new XMLNode(*n->children().front());
+           after = new XMLNode(*n->children().back());
+           child = before;
+    } else if (n->name() == "MementoUndoCommand") {
+           before = new XMLNode(*n->children().front());
+           child = before;
+    } else if (n->name() == "MementoRedoCommand") {
+           after = new XMLNode(*n->children().front());
+           child = after;
+    } else if (n->name() == "PlaylistCommand") {
+           before = new XMLNode(*n->children().front());
+           after = new XMLNode(*n->children().back());
+           child = before;
+    }
+                   
+    if (!child)
+    {
+       error << _("Tried to reconstitute a MementoCommand with no contents, failing. id=") << id.to_s() << endmsg;
+       return 0;
+    }
+
+
+    /* create command */
+    string obj_T = n->children().front()->name();
+    if (obj_T == "AudioRegion" || obj_T == "Region") {
+           if (audio_regions.count(id))
+                   return new MementoCommand<AudioRegion>(*audio_regions[id], before, after);
+    } else if (obj_T == "AudioSource") {
+           if (audio_sources.count(id))
+                   return new MementoCommand<AudioSource>(*audio_sources[id], before, after);
+    } else if (obj_T == "Location") {
+           return new MementoCommand<Location>(*_locations.get_location_by_id(id), before, after);
+    } else if (obj_T == "Locations") {
+           return new MementoCommand<Locations>(_locations, before, after);
+    } else if (obj_T == "TempoMap") {
+           return new MementoCommand<TempoMap>(*_tempo_map, before, after);
+    } else if (obj_T == "Playlist" || obj_T == "AudioPlaylist") {
+           if (Playlist *pl = playlist_by_name(child->property("name")->value()))
+                   return new MementoCommand<Playlist>(*pl, before, after);
+    } else if (obj_T == "Route") { // includes AudioTrack
+           return new MementoCommand<Route>(*route_by_id(id), before, after);
+    } else if (obj_T == "Curve") {
+           if (curves.count(id))
+                   return new MementoCommand<Curve>(*curves[id], before, after);
+    } else if (obj_T == "AutomationList") {
+           if (automation_lists.count(id))
+                   return new MementoCommand<AutomationList>(*automation_lists[id], before, after);
+    } else if (registry.count(id)) { // For Editor and AutomationLine which are off-limits here
+           return new MementoCommand<PBD::StatefulThingWithGoingAway>(*registry[id], before, after);
+    }
+
+    /* we failed */
+    error << _("could not reconstitute MementoCommand from XMLNode. id=") << id.to_s() << endmsg;
+    return 0;
+}
+
 // solo
 Session::GlobalSoloStateCommand::GlobalSoloStateCommand(Session &sess, void *src)
     : sess(sess), src(src)