summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorHans Fugal <hans@fugal.net>2006-08-12 21:49:20 +0000
committerHans Fugal <hans@fugal.net>2006-08-12 21:49:20 +0000
commit57f7f71ce3c1acae5a50e903d2dd472743df8043 (patch)
tree6bb6ea6e16a17bbc5e96ecdc70d839ef7b3a955c /libs
parentf995ac37860140c513e29c3bc58701474a7ed336 (diff)
r316@gandalf: fugalh | 2006-08-11 17:06:48 -0600
Reconstitution. Comiples, untested. git-svn-id: svn://localhost/ardour2/branches/undo@797 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs')
-rw-r--r--libs/ardour/ardour/automation_event.h2
-rw-r--r--libs/ardour/ardour/curve.h2
-rw-r--r--libs/ardour/ardour/location.h1
-rw-r--r--libs/ardour/ardour/session.h11
-rw-r--r--libs/ardour/audio_diskstream.cc2
-rw-r--r--libs/ardour/automation_event.cc4
-rw-r--r--libs/ardour/curve.cc3
-rw-r--r--libs/ardour/session.cc25
-rw-r--r--libs/ardour/session_command.cc79
-rw-r--r--libs/ardour/session_state.cc62
-rw-r--r--libs/ardour/session_transport.cc2
-rw-r--r--libs/pbd/pbd/memento_command.h82
-rw-r--r--libs/pbd/pbd/stateful.h3
-rw-r--r--libs/pbd/undo.cc8
14 files changed, 221 insertions, 65 deletions
diff --git a/libs/ardour/ardour/automation_event.h b/libs/ardour/ardour/automation_event.h
index 5864de73c6..dad94161d0 100644
--- a/libs/ardour/ardour/automation_event.h
+++ b/libs/ardour/ardour/automation_event.h
@@ -183,6 +183,8 @@ class AutomationList : public StateManager, public Stateful
}
};
+ static sigc::signal<void, AutomationList*> AutomationListCreated;
+
protected:
PBD::ID _id;
struct State : public ARDOUR::StateManager::State {
diff --git a/libs/ardour/ardour/curve.h b/libs/ardour/ardour/curve.h
index 7f8a43cfe1..7ba6b5fa6c 100644
--- a/libs/ardour/ardour/curve.h
+++ b/libs/ardour/ardour/curve.h
@@ -59,6 +59,8 @@ class Curve : public AutomationList
AutomationEventList::iterator closest_control_point_after (double xval);
void solve ();
+
+ static sigc::signal<void, Curve*> CurveCreated;
protected:
ControlEvent* point_factory (double,double) const;
diff --git a/libs/ardour/ardour/location.h b/libs/ardour/ardour/location.h
index ff953d1d78..beae4a6e07 100644
--- a/libs/ardour/ardour/location.h
+++ b/libs/ardour/ardour/location.h
@@ -149,6 +149,7 @@ class Locations : public Stateful, public StateManager
XMLNode& get_state (void);
int set_state (const XMLNode&);
PBD::ID id() { return _id; }
+ Location *get_location_by_id(PBD::ID);
Location* auto_loop_location () const;
Location* auto_punch_location () const;
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index e2b14eccfa..d067de4e68 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -302,6 +302,7 @@ class Session : public sigc::trackable, public Stateful
template<class T, class A> void foreach_route (T *obj, void (T::*func)(Route&, A), A arg);
boost::shared_ptr<Route> route_by_name (string);
+ boost::shared_ptr<Route> route_by_id (PBD::ID);
boost::shared_ptr<Route> route_by_remote_id (uint32_t id);
bool route_name_unique (string) const;
@@ -478,6 +479,7 @@ class Session : public sigc::trackable, public Stateful
int restore_state (string snapshot_name);
int save_template (string template_name);
int save_history (string snapshot_name = "");
+ int restore_history (string snapshot_name);
static int rename_template (string old_name, string new_name);
@@ -713,6 +715,10 @@ class Session : public sigc::trackable, public Stateful
sigc::signal<void> NamedSelectionAdded;
sigc::signal<void> NamedSelectionRemoved;
+ /* Curves and AutomationLists (TODO when they go away) */
+ void add_curve(Curve*);
+ void add_automation_list(AutomationList*);
+
/* fade curves */
float get_default_fade_length () const { return default_fade_msecs; }
@@ -840,6 +846,7 @@ class Session : public sigc::trackable, public Stateful
// these commands are implemented in libs/ardour/session_command.cc
Command *memento_command_factory(XMLNode *n);
+ void register_with_memento_command_factory(PBD::ID, Stateful *);
class GlobalSoloStateCommand : public Command
{
GlobalRouteBooleanState before, after;
@@ -1586,6 +1593,10 @@ class Session : public sigc::trackable, public Stateful
NamedSelection *named_selection_factory (string name);
NamedSelection *XMLNamedSelectionFactory (const XMLNode&);
+ /* CURVES and AUTOMATION LISTS */
+ std::map<PBD::ID, Curve*> curves;
+ std::map<PBD::ID, AutomationList*> automation_lists;
+
/* DEFAULT FADE CURVES */
float default_fade_steepness;
diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc
index 9619f404fa..d3e64104a0 100644
--- a/libs/ardour/audio_diskstream.cc
+++ b/libs/ardour/audio_diskstream.cc
@@ -1614,7 +1614,7 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca
_playlist->thaw ();
XMLNode &after = _playlist->get_state();
- _session.add_command (new MementoCommand<Playlist>(*_playlist, before, after));
+ _session.add_command (new MementoCommand<Playlist>(*_playlist, &before, &after));
}
mark_write_completed = true;
diff --git a/libs/ardour/automation_event.cc b/libs/ardour/automation_event.cc
index dc1767d1e7..cf69c634b1 100644
--- a/libs/ardour/automation_event.cc
+++ b/libs/ardour/automation_event.cc
@@ -64,6 +64,8 @@ AutomationList::AutomationList (double defval, bool with_state)
if (!no_state) {
save_state (_("initial"));
}
+
+ AutomationListCreated(this);
}
AutomationList::AutomationList (const AutomationList& other)
@@ -91,6 +93,7 @@ AutomationList::AutomationList (const AutomationList& other)
}
mark_dirty ();
+ AutomationListCreated(this);
}
AutomationList::AutomationList (const AutomationList& other, double start, double end)
@@ -123,6 +126,7 @@ AutomationList::AutomationList (const AutomationList& other, double start, doubl
delete section;
mark_dirty ();
+ AutomationListCreated(this);
}
AutomationList::~AutomationList()
diff --git a/libs/ardour/curve.cc b/libs/ardour/curve.cc
index 977b6dfd7b..5879cb5988 100644
--- a/libs/ardour/curve.cc
+++ b/libs/ardour/curve.cc
@@ -45,6 +45,7 @@ Curve::Curve (double minv, double maxv, double canv, bool nostate)
{
min_yval = minv;
max_yval = maxv;
+ CurveCreated(this);
}
Curve::Curve (const Curve& other)
@@ -52,6 +53,7 @@ Curve::Curve (const Curve& other)
{
min_yval = other.min_yval;
max_yval = other.max_yval;
+ CurveCreated(this);
}
Curve::Curve (const Curve& other, double start, double end)
@@ -59,6 +61,7 @@ Curve::Curve (const Curve& other, double start, double end)
{
min_yval = other.min_yval;
max_yval = other.max_yval;
+ CurveCreated(this);
}
Curve::~Curve ()
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index 4a0d820381..1bd11cacc0 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -2227,6 +2227,20 @@ Session::route_by_name (string name)
}
shared_ptr<Route>
+Session::route_by_id (PBD::ID id)
+{
+ shared_ptr<RouteList> r = routes.reader ();
+
+ for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
+ if ((*i)->id() == id) {
+ return *i;
+ }
+ }
+
+ return shared_ptr<Route> ((Route*) 0);
+}
+
+shared_ptr<Route>
Session::route_by_remote_id (uint32_t id)
{
shared_ptr<RouteList> r = routes.reader ();
@@ -3794,3 +3808,14 @@ Session::set_xfade_model (CrossfadeModel xm)
}
}
+void
+Session::add_curve(Curve *curve)
+{
+ curves[curve->id()] = curve;
+}
+
+void
+Session::add_automation_list(AutomationList *al)
+{
+ automation_lists[al->id()] = al;
+}
diff --git a/libs/ardour/session_command.cc b/libs/ardour/session_command.cc
index 556c6ea9a3..4021fae573 100644
--- a/libs/ardour/session_command.cc
+++ b/libs/ardour/session_command.cc
@@ -2,24 +2,85 @@
#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>
+using namespace PBD;
+#include "i18n.h"
+
namespace ARDOUR {
+static map<PBD::ID, Stateful*> registry;
+
+void Session::register_with_memento_command_factory(PBD::ID id, Stateful *ptr)
+{
+ registry[id] = ptr;
+}
+
Command *Session::memento_command_factory(XMLNode *n)
{
PBD::ID id;
- XMLNode *before, *after;
+ XMLNode *before = 0, *after = 0;
+
+ /* get id */
+ id = PBD::ID(n->property("obj_id")->value());
+
+ /* get before/after */
+ if (n->name() == "MementoCommand")
+ {
+ before = n->children().front();
+ after = n->children().back();
+ } else if (n->name() == "MementoUndoCommand")
+ before = n->children().front();
+ else if (n->name() == "MementoRedoCommand")
+ after = n->children().front();
- /* get obj_id */
- /* get before and/or after */
+ /* 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(before->property("name")->value()))
+ return new MementoCommand<Playlist>(*pl, before, after);
+ }
+ else if (obj_T == "Route") // inlcudes AudioTrack
+ return new MementoCommand<Route>(*route_by_id(id), before, after);
+ // For Editor and AutomationLine which are off-limits here
+ else if (registry.count(id))
+ return new MementoCommand<Stateful>(*registry[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);
+ }
- /* get an object by id by trial and error, and use it to construct an
- * appropriate memento command */
- // e.g.
- if (Diskstream *obj = diskstream_by_id(id))
- return new MementoCommand<Diskstream>(*obj, *before, *after);
- // etc.
+ /* we failed */
+ error << _("could not reconstitute MementoCommand from XMLNode. id=") << id.to_s() << endmsg;
+ return 0;
}
// solo
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index ebf2b6efd5..903d6f558a 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -266,6 +266,8 @@ Session::first_stage_init (string fullpath, string snapshot_name)
Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
AudioDiskstream::DiskstreamCreated.connect (mem_fun (*this, &Session::add_diskstream));
NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
+ Curve::CurveCreated.connect (mem_fun (*this, &Session::add_curve));
+ AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
Controllable::Created.connect (mem_fun (*this, &Session::add_controllable));
Controllable::GoingAway.connect (mem_fun (*this, &Session::remove_controllable));
@@ -3328,3 +3330,63 @@ Session::save_history (string snapshot_name)
return 0;
}
+
+int
+Session::restore_history (string snapshot_name)
+{
+ XMLTree tree;
+ string xmlpath;
+
+ /* read xml */
+ xmlpath = _path + snapshot_name + ".history";
+
+ if (access (xmlpath.c_str(), F_OK)) {
+ error << string_compose(_("%1: session history file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
+ return 1;
+ }
+
+ if (!tree.read (xmlpath)) {
+ error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
+ return -1;
+ }
+
+ /* replace history */
+ history.clear();
+ for (XMLNodeConstIterator it = tree.root()->children().begin();
+ it != tree.root()->children().end();
+ it++)
+ {
+ XMLNode *t = *it;
+ UndoTransaction ut;
+ struct timeval tv;
+
+ ut.set_name(t->property("name")->value());
+ stringstream ss(t->property("tv_sec")->value());
+ ss >> tv.tv_sec;
+ ss.str(t->property("tv_usec")->value());
+ ss >> tv.tv_usec;
+ ut.set_timestamp(tv);
+
+ for (XMLNodeConstIterator child_it = t->children().begin();
+ child_it != t->children().end();
+ child_it++)
+ {
+ XMLNode *n = *child_it;
+ Command *c;
+ if (n->name() == "MementoCommand" ||
+ n->name() == "MementoUndoCommand" ||
+ n->name() == "MementoRedoCommand")
+ {
+ c = memento_command_factory(n);
+ if (c)
+ ut.add_command(c);
+ }
+ else
+ {
+ error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
+ }
+ }
+ history.add(ut);
+ }
+ return 0;
+}
diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc
index 1f70a9ebb8..0e3895caf1 100644
--- a/libs/ardour/session_transport.cc
+++ b/libs/ardour/session_transport.cc
@@ -324,7 +324,7 @@ Session::non_realtime_stop (bool abort)
XMLNode &before = loc->get_state();
loc->set_end(_transport_frame);
XMLNode &after = loc->get_state();
- add_command (new MementoCommand<Location>(*loc, before, after));
+ add_command (new MementoCommand<Location>(*loc, &before, &after));
}
_end_location_is_free = false;
diff --git a/libs/pbd/pbd/memento_command.h b/libs/pbd/pbd/memento_command.h
index 122dcb4c86..3a72fc9841 100644
--- a/libs/pbd/pbd/memento_command.h
+++ b/libs/pbd/pbd/memento_command.h
@@ -36,70 +36,44 @@ class MementoCommand : public Command
public:
MementoCommand(XMLNode &state);
MementoCommand(obj_T &obj,
- XMLNode &before,
- XMLNode &after
+ XMLNode *before,
+ XMLNode *after
)
: obj(obj), before(before), after(after) {}
- void operator() () { obj.set_state(after); }
- void undo() { obj.set_state(before); }
+ void operator() ()
+ {
+ if (after)
+ obj.set_state(*after);
+ }
+ void undo()
+ {
+ if (before)
+ obj.set_state(*before);
+ }
virtual XMLNode &get_state()
{
- XMLNode *node = new XMLNode("MementoCommand");
+ string name;
+ if (before && after)
+ name = "MementoCommand";
+ else if (before)
+ name = "MementoUndoCommand";
+ else
+ name = "MementoRedoCommand";
+
+ XMLNode *node = new XMLNode(name);
node->add_property("obj_id", obj.id().to_s());
node->add_property("type_name", typeid(obj).name());
- node->add_child_copy(before);
- node->add_child_copy(after);
+
+ if (before)
+ node->add_child_copy(*before);
+ if (after)
+ node->add_child_copy(*after);
+
return *node;
}
protected:
obj_T &obj;
- XMLNode &before, &after;
-};
-
-template <class obj_T>
-class MementoUndoCommand : public Command
-{
-public:
- MementoUndoCommand(XMLNode &state);
- MementoUndoCommand(obj_T &obj,
- XMLNode &before)
- : obj(obj), before(before) {}
- void operator() () { /* noop */ }
- void undo() { obj.set_state(before); }
- virtual XMLNode &get_state()
- {
- XMLNode *node = new XMLNode("MementoUndoCommand");
- node->add_property("obj_id", obj.id().to_s());
- node->add_property("type_name", typeid(obj).name());
- node->add_child_copy(before);
- return *node;
- }
-protected:
- obj_T &obj;
- XMLNode &before;
-};
-
-template <class obj_T>
-class MementoRedoCommand : public Command
-{
-public:
- MementoRedoCommand(XMLNode &state);
- MementoRedoCommand(obj_T &obj,
- XMLNode &after)
- : obj(obj), after(after) {}
- void operator() () { obj.set_state(after); }
- void undo() { /* noop */ }
- virtual XMLNode &get_state()
- {
- XMLNode *node = new XMLNode("MementoRedoCommand");
- node->add_property("obj_id", obj.id().to_s());
- node->add_property("type_name", typeid(obj).name());
- node->add_child_copy(after);
- return *node;
- }
-protected:
- obj_T &obj;
- XMLNode &after;
+ XMLNode *before, *after;
};
#endif // __lib_pbd_memento_h__
diff --git a/libs/pbd/pbd/stateful.h b/libs/pbd/pbd/stateful.h
index 3038f16b4f..5adddfc1c0 100644
--- a/libs/pbd/pbd/stateful.h
+++ b/libs/pbd/pbd/stateful.h
@@ -22,6 +22,7 @@
#define __pbd_stateful_h__
#include <string>
+#include <pbd/id.h>
class XMLNode;
@@ -41,10 +42,12 @@ class Stateful {
virtual void add_instant_xml (XMLNode&, const std::string& dir);
XMLNode *instant_xml (const std::string& str, const std::string& dir);
+ PBD::ID id() { return _id; }
protected:
XMLNode *_extra_xml;
XMLNode *_instant_xml;
+ PBD::ID _id;
};
#endif /* __pbd_stateful_h__ */
diff --git a/libs/pbd/undo.cc b/libs/pbd/undo.cc
index 8d1b416c16..6f421de84e 100644
--- a/libs/pbd/undo.cc
+++ b/libs/pbd/undo.cc
@@ -23,6 +23,7 @@
#include <pbd/undo.h>
#include <pbd/xml++.h>
#include <string>
+#include <sstream>
using namespace std;
using namespace sigc;
@@ -87,6 +88,13 @@ UndoTransaction::redo ()
XMLNode &UndoTransaction::get_state()
{
XMLNode *node = new XMLNode ("UndoTransaction");
+ stringstream ss;
+ ss << _timestamp.tv_sec;
+ node->add_property("tv_sec", ss.str());
+ ss.str("");
+ ss << _timestamp.tv_usec;
+ node->add_property("tv_usec", ss.str());
+ node->add_property("name", _name);
list<Command*>::iterator it;
for (it=actions.begin(); it!=actions.end(); it++)