diff options
Diffstat (limited to 'libs')
-rw-r--r-- | libs/ardour/ardour/midi_automation_list_binder.h | 2 | ||||
-rw-r--r-- | libs/ardour/midi_automation_list_binder.cc | 2 | ||||
-rw-r--r-- | libs/ardour/session_command.cc | 14 | ||||
-rw-r--r-- | libs/ardour/wscript | 1 | ||||
-rw-r--r-- | libs/pbd/pbd/memento_command.h | 30 |
5 files changed, 34 insertions, 15 deletions
diff --git a/libs/ardour/ardour/midi_automation_list_binder.h b/libs/ardour/ardour/midi_automation_list_binder.h index 95576b47de..89c6cdb90b 100644 --- a/libs/ardour/ardour/midi_automation_list_binder.h +++ b/libs/ardour/ardour/midi_automation_list_binder.h @@ -33,7 +33,7 @@ public: MidiAutomationListBinder (boost::shared_ptr<ARDOUR::MidiSource>, Evoral::Parameter); MidiAutomationListBinder (XMLNode *, ARDOUR::Session::SourceMap const &); - ARDOUR::AutomationList* get (); + ARDOUR::AutomationList* get () const; void add_state (XMLNode *); private: diff --git a/libs/ardour/midi_automation_list_binder.cc b/libs/ardour/midi_automation_list_binder.cc index 0f8e4884ca..fbb87c5cfa 100644 --- a/libs/ardour/midi_automation_list_binder.cc +++ b/libs/ardour/midi_automation_list_binder.cc @@ -49,7 +49,7 @@ MidiAutomationListBinder::MidiAutomationListBinder (XMLNode* node, Session::Sour } AutomationList* -MidiAutomationListBinder::get () +MidiAutomationListBinder::get () const { boost::shared_ptr<MidiModel> model = _source->model (); assert (model); diff --git a/libs/ardour/session_command.cc b/libs/ardour/session_command.cc index c240a4aa94..e5ddd0a097 100644 --- a/libs/ardour/session_command.cc +++ b/libs/ardour/session_command.cc @@ -34,6 +34,7 @@ #include "ardour/session_playlists.h" #include "ardour/region_factory.h" #include "ardour/midi_automation_list_binder.h" +#include "ardour/crossfade_binder.h" #include "ardour/crossfade.h" #include "pbd/error.h" #include "pbd/id.h" @@ -143,11 +144,16 @@ Session::memento_command_factory(XMLNode *n) cerr << "Alist " << id << " not found\n"; } else if (obj_T == "ARDOUR::Crossfade") { - boost::shared_ptr<Crossfade> c = playlists->find_crossfade (id); - if (c) { - return new MementoCommand<Crossfade> (*c.get(), before, after); + if (have_id) { + boost::shared_ptr<Crossfade> c = playlists->find_crossfade (id); + if (c) { + return new MementoCommand<Crossfade> (*c.get(), before, after); + } } else { - error << string_compose (X_("Crossfade %1 not found in session"), id) << endmsg; + return new MementoCommand<Crossfade> ( + new CrossfadeBinder (n, playlists), + before, after + ); } } else if (registry.count(id)) { // For Editor and AutomationLine which are off-limits herea diff --git a/libs/ardour/wscript b/libs/ardour/wscript index b347e73e7e..1b71f58298 100644 --- a/libs/ardour/wscript +++ b/libs/ardour/wscript @@ -71,6 +71,7 @@ libardour_sources = [ 'control_protocol_manager.cc', 'control_protocol_search_path.cc', 'crossfade.cc', + 'crossfade_binder.cc', 'cycle_timer.cc', 'data_type.cc', 'default_click.cc', diff --git a/libs/pbd/pbd/memento_command.h b/libs/pbd/pbd/memento_command.h index 8b412937ef..45cb100a36 100644 --- a/libs/pbd/pbd/memento_command.h +++ b/libs/pbd/pbd/memento_command.h @@ -34,20 +34,32 @@ /** A class that can return a Stateful object which is the subject of a MementoCommand. * * The existence of this class means that the undo record can refer to objects which - * don't exist in the session file. Currently this is just used for MIDI automation; - * when MIDI automation is edited, undo records are written for the AutomationList being - * changed. However this AutomationList is a temporary structure, built by a MidiModel, - * which doesn't get written to the session file. Hence we need to be able to go from - * a MidiSource and Parameter to an AutomationList. This Binder mechanism allows this - * through MidiAutomationListBinder; the undo record stores the source and parameter, + * don't exist in the session file. Currently this is used for + * + * 1. MIDI automation; when MIDI automation is edited, undo records are + * written for the AutomationList being changed. However this AutomationList + * is a temporary structure, built by a MidiModel, which doesn't get written + * to the session file. Hence we need to be able to go from a MidiSource and + * Parameter to an AutomationList. This Binder mechanism allows this through + * MidiAutomationListBinder; the undo record stores the source and parameter, * and these are bound to an AutomationList by the Binder. + * + * 2. Crossfades; unlike regions, these are completely removed from a session + * when they are deleted. This means that the undo record can contain + * references to non-existant crossfades. To get around this, CrossfadeBinder + * can do `just-in-time' binding from the crossfade ID. */ template <class obj_T> class MementoCommandBinder : public PBD::Destructible { public: /** @return Stateful object to operate on */ - virtual obj_T* get () = 0; + virtual obj_T* get () const = 0; + + /** @return Name of our type */ + virtual std::string type_name () const { + return PBD::demangled_name (*get ()); + } /** Add our own state to an XMLNode */ virtual void add_state (XMLNode *) = 0; @@ -64,7 +76,7 @@ public: _object.Destroyed.connect_same_thread (_object_death_connection, boost::bind (&SimpleMementoCommandBinder::object_died, this)); } - obj_T* get () { + obj_T* get () const { return &_object; } @@ -140,7 +152,7 @@ public: XMLNode* node = new XMLNode(name); _binder->add_state (node); - node->add_property("type_name", demangled_name (*_binder->get())); + node->add_property ("type_name", _binder->type_name ()); if (before) { node->add_child_copy(*before); |