diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2010-02-08 19:39:17 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2010-02-08 19:39:17 +0000 |
commit | e2baff4f7d00c97dc4192c5ac573aeee8950b2ae (patch) | |
tree | d099f62d821f86980b062d2fc93aa6e8c9203ba2 /libs | |
parent | 1afb1cfea4f2ea66962faef01d729014bdc9eb56 (diff) |
new RegionCommand object; remove unused string argument from Region::thaw(); add map<ID,Region> in RegionFactory so that we can look up regions by ID
git-svn-id: svn://localhost/ardour2/branches/3.0@6652 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs')
-rw-r--r-- | libs/ardour/ardour/region.h | 2 | ||||
-rw-r--r-- | libs/ardour/ardour/region_command.h | 104 | ||||
-rw-r--r-- | libs/ardour/ardour/region_factory.h | 12 | ||||
-rw-r--r-- | libs/ardour/audioregion.cc | 2 | ||||
-rw-r--r-- | libs/ardour/enums.cc | 27 | ||||
-rw-r--r-- | libs/ardour/export_graph_builder.cc | 2 | ||||
-rw-r--r-- | libs/ardour/mute_master.cc | 2 | ||||
-rw-r--r-- | libs/ardour/playlist.cc | 8 | ||||
-rw-r--r-- | libs/ardour/region.cc | 2 | ||||
-rw-r--r-- | libs/ardour/region_command.cc | 274 | ||||
-rw-r--r-- | libs/ardour/region_factory.cc | 40 | ||||
-rw-r--r-- | libs/ardour/session.cc | 4 | ||||
-rw-r--r-- | libs/ardour/session_command.cc | 8 | ||||
-rw-r--r-- | libs/ardour/session_state.cc | 11 | ||||
-rw-r--r-- | libs/ardour/wscript | 1 |
15 files changed, 490 insertions, 9 deletions
diff --git a/libs/ardour/ardour/region.h b/libs/ardour/ardour/region.h index 4cae00c532..310bd582cd 100644 --- a/libs/ardour/ardour/region.h +++ b/libs/ardour/ardour/region.h @@ -162,7 +162,7 @@ class Region void recompute_position_from_lock_style (); void freeze (); - void thaw (const std::string& why); + void thaw (); bool covers (nframes_t frame) const { return first_frame() <= frame && frame <= last_frame(); diff --git a/libs/ardour/ardour/region_command.h b/libs/ardour/ardour/region_command.h new file mode 100644 index 0000000000..07589b70c7 --- /dev/null +++ b/libs/ardour/ardour/region_command.h @@ -0,0 +1,104 @@ +#ifndef __libardour_region_command_h__ +#define __libardour_region_command_h__ + +#include <sstream> +#include <string> +#include <vector> + +#include "pbd/command.h" + +namespace ARDOUR { + +class Region; + +class RegionCommand : public Command { + public: + enum Property { + Name, + PositionLockStyle, + Length, + Start, + Position, + PositionOnTop, + Layer, + SyncPosition, + Hidden, + Muted, + Opaque, + Locked, + PositionLocked, + + /* audio */ + ScaleAmplitude, + FadeInActive, + FadeInShape, + FadeInLength, + FadeIn, + FadeOutActive, + FadeOutShape, + FadeOutLength, + FadeOut, + EnvelopActive, + DefaultEnvelope + }; + + RegionCommand (boost::shared_ptr<Region>); + RegionCommand (boost::shared_ptr<Region>, const XMLNode&); + RegionCommand (boost::shared_ptr<Region>, Property, const std::string& target_value); + + + /* this is mildly type-unsafe, in that we could pass in the wrong types for before&after + given the value of `property'. however, its just as safe as a variant that accepts + strings, and makes this whole class much easier to use. + */ + + template<typename T> void add_property_change (Property property, const T& before, const T& after) { + std::stringstream sb, sa; + + /* in case T is a floating point value ... + */ + + sb.precision (15); + sa.precision (15); + + /* format */ + + sb << before; + sa << after; + + /* and stash it away */ + + _add_property_change (property, sb.str(), sa.str()); + } + + void set_name (const std::string& str) { _name = str; } + const std::string& name() const { return _name; } + + void operator() (); + void undo(); + void redo() { (*this)(); } + + XMLNode &get_state(); + int set_state (const XMLNode&, int /*version*/); + + private: + struct PropertyTriple { + Property property; + std::string before; + std::string after; + + PropertyTriple (Property p, const std::string& b, const std::string& a) + : property (p), before (b), after (a) {} + }; + + boost::shared_ptr<Region> region; + typedef std::vector<PropertyTriple> PropertyTriples; + PropertyTriples property_changes; + + void do_property_change (Property prop, const std::string& value); + void _add_property_change (Property, const std::string& before_value, const std::string& after_value); +}; + +} + +#endif /* __libardour_region_command_h__ */ diff --git a/libs/ardour/ardour/region_factory.h b/libs/ardour/ardour/region_factory.h index b53e9490de..64d3417287 100644 --- a/libs/ardour/ardour/region_factory.h +++ b/libs/ardour/ardour/region_factory.h @@ -20,6 +20,10 @@ #ifndef __ardour_region_factory_h__ #define __ardour_region_factory_h__ +#include <map> + +#include "pbd/id.h" + #include "ardour/types.h" #include "ardour/region.h" @@ -33,6 +37,10 @@ class AudioRegion; class RegionFactory { public: + + static boost::shared_ptr<Region> region_by_id (const PBD::ID&); + static void clear_map (); + /** This is emitted only when a new id is assigned. Therefore, in a pure Region copy, it will not be emitted. @@ -59,6 +67,10 @@ class RegionFactory { static boost::shared_ptr<Region> create (const SourceList &, nframes_t start, nframes_t length, const std::string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true); static boost::shared_ptr<Region> create (Session&, XMLNode&, bool); static boost::shared_ptr<Region> create (SourceList &, const XMLNode&); + + private: + static std::map<PBD::ID,boost::weak_ptr<Region> > region_map; + static void map_add (boost::shared_ptr<Region>); }; } diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc index 729398cf21..e904541ac4 100644 --- a/libs/ardour/audioregion.cc +++ b/libs/ardour/audioregion.cc @@ -767,7 +767,7 @@ AudioRegion::set_live_state (const XMLNode& node, int version, Change& what_chan } _envelope->thaw (); - thaw (""); + thaw (); if (send) { cerr << _name << ": audio final change: " << hex << what_changed << dec << endl; diff --git a/libs/ardour/enums.cc b/libs/ardour/enums.cc index 7d07a5a95f..9a512fe708 100644 --- a/libs/ardour/enums.cc +++ b/libs/ardour/enums.cc @@ -33,6 +33,7 @@ #include "ardour/midi_track.h" #include "ardour/mute_master.h" #include "ardour/panner.h" +#include "ardour/region_command.h" #include "ardour/route_group.h" #include "ardour/session.h" #include "ardour/track.h" @@ -121,6 +122,7 @@ setup_enum_writer () Session::PostTransportWork _Session_PostTransportWork; Session::SlaveState _Session_SlaveState; MTC_Status _MIDI_MTC_Status; + RegionCommand::Property _RegionCommandProperty; #define REGISTER(e) enum_writer.register_distinct (typeid(e).name(), i, s); i.clear(); s.clear() #define REGISTER_BITS(e) enum_writer.register_bits (typeid(e).name(), i, s); i.clear(); s.clear() @@ -583,6 +585,31 @@ setup_enum_writer () REGISTER_ENUM(Groove); REGISTER(_QuantizeType); + REGISTER_CLASS_ENUM (RegionCommand, Name); + REGISTER_CLASS_ENUM (RegionCommand, PositionLockStyle); + REGISTER_CLASS_ENUM (RegionCommand, Length); + REGISTER_CLASS_ENUM (RegionCommand, Start); + REGISTER_CLASS_ENUM (RegionCommand, Position); + REGISTER_CLASS_ENUM (RegionCommand, PositionOnTop); + REGISTER_CLASS_ENUM (RegionCommand, Layer); + REGISTER_CLASS_ENUM (RegionCommand, SyncPosition); + REGISTER_CLASS_ENUM (RegionCommand, Hidden); + REGISTER_CLASS_ENUM (RegionCommand, Muted); + REGISTER_CLASS_ENUM (RegionCommand, Opaque); + REGISTER_CLASS_ENUM (RegionCommand, Locked); + REGISTER_CLASS_ENUM (RegionCommand, PositionLocked); + REGISTER_CLASS_ENUM (RegionCommand, ScaleAmplitude); + REGISTER_CLASS_ENUM (RegionCommand, FadeInActive); + REGISTER_CLASS_ENUM (RegionCommand, FadeInShape); + REGISTER_CLASS_ENUM (RegionCommand, FadeInLength); + REGISTER_CLASS_ENUM (RegionCommand, FadeIn); + REGISTER_CLASS_ENUM (RegionCommand, FadeOutActive); + REGISTER_CLASS_ENUM (RegionCommand, FadeOutShape); + REGISTER_CLASS_ENUM (RegionCommand, FadeOutLength); + REGISTER_CLASS_ENUM (RegionCommand, FadeOut); + REGISTER_CLASS_ENUM (RegionCommand, EnvelopActive); + REGISTER_CLASS_ENUM (RegionCommand, DefaultEnvelope); + REGISTER(_RegionCommandProperty); } } /* namespace ARDOUR */ diff --git a/libs/ardour/export_graph_builder.cc b/libs/ardour/export_graph_builder.cc index 3b1d1e3838..01c2934555 100644 --- a/libs/ardour/export_graph_builder.cc +++ b/libs/ardour/export_graph_builder.cc @@ -44,7 +44,7 @@ ExportGraphBuilder::~ExportGraphBuilder () } int -ExportGraphBuilder::process (nframes_t frames, bool last_cycle) +ExportGraphBuilder::process (nframes_t /* frames */, bool last_cycle) { for (ChannelMap::iterator it = channels.begin(); it != channels.end(); ++it) { it->first->read (process_buffer, process_buffer_frames); diff --git a/libs/ardour/mute_master.cc b/libs/ardour/mute_master.cc index 14411580fd..e7810b27fd 100644 --- a/libs/ardour/mute_master.cc +++ b/libs/ardour/mute_master.cc @@ -34,7 +34,7 @@ const MuteMaster::MutePoint MuteMaster::AllPoints = MutePoint (MuteMaster::PreFa MuteMaster::Listen| MuteMaster::Main); -MuteMaster::MuteMaster (Session& s, const std::string& name) +MuteMaster::MuteMaster (Session&, const std::string&) : _mute_point (MutePoint (0)) { } diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc index 689c1fe35b..39bd5695b4 100644 --- a/libs/ardour/playlist.cc +++ b/libs/ardour/playlist.cc @@ -762,7 +762,7 @@ Playlist::partition (nframes_t start, nframes_t end, bool cut) partition_internal (start, end, cut, thawlist); for (RegionList::iterator i = thawlist.begin(); i != thawlist.end(); ++i) { - (*i)->thaw ("separation"); + (*i)->thaw (); } } @@ -1027,7 +1027,7 @@ Playlist::cut (nframes_t start, nframes_t cnt, bool result_is_hidden) partition_internal (start, start+cnt-1, true, thawlist); for (RegionList::iterator i = thawlist.begin(); i != thawlist.end(); ++i) { - (*i)->thaw ("playlist cut"); + (*i)->thaw (); } return the_copy; @@ -1900,7 +1900,7 @@ Playlist::set_state (const XMLNode& node, int version) region->freeze (); if (region->set_live_state (*child, version, what_changed, false)) { - region->thaw (""); + region->thaw (); continue; } @@ -1915,7 +1915,7 @@ Playlist::set_state (const XMLNode& node, int version) // So that layer_op ordering doesn't get screwed up region->set_last_layer_op( region->layer()); - region->thaw (""); + region->thaw (); } } diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc index 1f4d6f0f91..f1dd92abe5 100644 --- a/libs/ardour/region.cc +++ b/libs/ardour/region.cc @@ -1324,7 +1324,7 @@ Region::freeze () } void -Region::thaw (const string& /*why*/) +Region::thaw () { Change what_changed = Change (0); diff --git a/libs/ardour/region_command.cc b/libs/ardour/region_command.cc new file mode 100644 index 0000000000..02a542e6c7 --- /dev/null +++ b/libs/ardour/region_command.cc @@ -0,0 +1,274 @@ +#include "pbd/convert.h" +#include "pbd/xml++.h" +#include "pbd/locale_guard.h" +#include "pbd/enumwriter.h" + +#include "ardour/region.h" +#include "ardour/region_command.h" +#include "ardour/utils.h" + +#include "i18n.h" + +using namespace ARDOUR; +using namespace PBD; +using namespace std; + +RegionCommand::RegionCommand (boost::shared_ptr<Region> r, const XMLNode& node) + : region (r) +{ + if (set_state (node, 0)) { + throw failed_constructor(); + } +} + +RegionCommand::RegionCommand (boost::shared_ptr<Region> r) + : region (r) +{ +} + +RegionCommand::RegionCommand (boost::shared_ptr<Region> r, Property prop, const std::string& target_value) + : region (r) +{ + LocaleGuard lg ("POSIX"); + string before; + char buf[128]; + + /* get current value as a string */ + + switch (prop) { + case Name: + before = r->name(); + break; + case PositionLockStyle: + before = enum_2_string (r->positional_lock_style()); + break; + case Length: + snprintf (buf, sizeof (buf), "%" PRId32, r->length()); + before = buf; + break; + case Start: + snprintf (buf, sizeof (buf), "%" PRId32, r->start()); + before = buf; + break; + case Position: + snprintf (buf, sizeof (buf), "%" PRId32, r->position()); + before = buf; + break; + case PositionOnTop: + snprintf (buf, sizeof (buf), "%" PRId32, r->position()); + before = buf; + break; + case Layer: + snprintf (buf, sizeof (buf), "%" PRId32, r->layer()); + before = buf; + break; + case SyncPosition: + snprintf (buf, sizeof (buf), "%" PRId32, r->sync_position()); + before = buf; + break; + case Hidden: + before = (r->hidden() ? "yes" : "no"); + break; + case Muted: + before = (r->muted() ? "yes" : "no"); + break; + case Opaque: + before = (r->opaque() ? "yes" : "no"); + break; + case Locked: + before = (r->locked() ? "yes" : "no"); + break; + case PositionLocked: + before = (r->position_locked() ? "yes" : "no"); + break; + + /* audio */ + + case ScaleAmplitude: + break; + case FadeInActive: + break; + case FadeInShape: + break; + case FadeInLength: + break; + case FadeIn: + break; + case FadeOutActive: + break; + case FadeOutShape: + break; + case FadeOutLength: + break; + case FadeOut: + break; + case EnvelopActive: + break; + case DefaultEnvelope: + break; + + } + + add_property_change (prop, before, target_value); +} + +void +RegionCommand::_add_property_change (Property prop, const std::string& before, const std::string& after) +{ + property_changes.push_back (PropertyTriple (prop, before, after)); +} + +void +RegionCommand::operator() () +{ + region->freeze (); + for (PropertyTriples::iterator i= property_changes.begin(); i != property_changes.end(); ++i) { + do_property_change (i->property, i->after); + } + region->thaw (); +} + +void +RegionCommand::undo () +{ + region->freeze (); + for (PropertyTriples::iterator i= property_changes.begin(); i != property_changes.end(); ++i) { + do_property_change (i->property, i->before); + } + region->thaw (); +} + +void +RegionCommand::do_property_change (Property prop, const std::string& value) +{ + Region::PositionLockStyle pls; + + switch (prop) { + case Name: + region->set_name (value); + break; + case PositionLockStyle: + region->set_position_lock_style ((Region::PositionLockStyle) string_2_enum (value, pls)); + break; + case Length: + region->set_length (atoll (value), this); + break; + case Start: + region->set_start (atoll (value), this); + break; + case Position: + region->set_position (atoll (value), this); + break; + case PositionOnTop: + region->set_position_on_top (atoll (value), this); + break; + case Layer: + region->set_layer (atoi (value)); + break; + case SyncPosition: + region->set_sync_position (atoi (value)); + break; + case Hidden: + region->set_hidden (string_is_affirmative (value)); + break; + case Muted: + region->set_muted (string_is_affirmative (value)); + break; + case Opaque: + region->set_opaque (string_is_affirmative (value)); + break; + case Locked: + region->set_locked (string_is_affirmative (value)); + break; + case PositionLocked: + region->set_position_locked (string_is_affirmative (value)); + break; + + /* audio */ + + case ScaleAmplitude: + break; + case FadeInActive: + break; + case FadeInShape: + break; + case FadeInLength: + break; + case FadeIn: + break; + case FadeOutActive: + break; + case FadeOutShape: + break; + case FadeOutLength: + break; + case FadeOut: + break; + case EnvelopActive: + break; + case DefaultEnvelope: + break; + + } +} + +XMLNode& +RegionCommand::get_state () +{ + XMLNode* node = new XMLNode (X_("RegionCommand")); + XMLNode* child; + + node->add_property (X_("region"), region->id().to_s()); + + for (PropertyTriples::iterator i = property_changes.begin(); i != property_changes.end(); ++i) { + + child = new XMLNode (X_("Op")); + + child->add_property (X_("property"), enum_2_string (i->property)); + child->add_property (X_("before"), i->before); + child->add_property (X_("after"), i->after); + + node->add_child_nocopy (*child); + } + + return *node; +} + +int +RegionCommand::set_state (const XMLNode& node, int /* version */) +{ + const XMLNodeList& children (node.children()); + Property property; + string before; + string after; + const XMLProperty* prop; + + for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) { + + if ((*i)->name() != X_("Op")) { + continue; + } + + if ((prop = (*i)->property (X_("property"))) == 0) { + return -1; + } + + property = (Property) string_2_enum (prop->value(), property); + + if ((prop = (*i)->property (X_("before"))) == 0) { + return -1; + } + + before = prop->value(); + + if ((prop = (*i)->property (X_("after"))) == 0) { + return -1; + } + + after = prop->value(); + + add_property_change (property, before, after); + } + + return 0; +} diff --git a/libs/ardour/region_factory.cc b/libs/ardour/region_factory.cc index 70ea326230..273066855b 100644 --- a/libs/ardour/region_factory.cc +++ b/libs/ardour/region_factory.cc @@ -35,6 +35,7 @@ using namespace ARDOUR; using namespace PBD; PBD::Signal1<void,boost::shared_ptr<Region> > RegionFactory::CheckNewRegion; +map<PBD::ID,boost::weak_ptr<Region> > RegionFactory::region_map; boost::shared_ptr<Region> RegionFactory::create (boost::shared_ptr<Region> region, nframes_t start, @@ -50,6 +51,7 @@ RegionFactory::create (boost::shared_ptr<Region> region, nframes_t start, boost::shared_ptr<AudioRegion> arp (ar); boost::shared_ptr<Region> ret (boost::static_pointer_cast<Region> (arp)); ret->unlock_property_changes (); + map_add (ret); if (announce) { CheckNewRegion (ret); } @@ -59,6 +61,7 @@ RegionFactory::create (boost::shared_ptr<Region> region, nframes_t start, boost::shared_ptr<MidiRegion> arp (ar); boost::shared_ptr<Region> ret (boost::static_pointer_cast<Region> (arp)); ret->unlock_property_changes (); + map_add (ret); if (announce) { CheckNewRegion (ret); } @@ -82,6 +85,7 @@ RegionFactory::create (boost::shared_ptr<const Region> region) boost_debug_shared_ptr_mark_interesting (arn, "Region"); boost::shared_ptr<Region> ret (arn); ret->unlock_property_changes (); + map_add (ret); /* pure copy constructor - no CheckNewRegion emitted */ return ret; } else if ((mr = boost::dynamic_pointer_cast<const MidiRegion>(region)) != 0) { @@ -122,6 +126,7 @@ RegionFactory::create (boost::shared_ptr<Region> region, const SourceList& srcs, boost::shared_ptr<AudioRegion> arp (ar); boost::shared_ptr<Region> ret (boost::static_pointer_cast<Region> (arp)); ret->unlock_property_changes (); + map_add (ret); if (announce) { CheckNewRegion (ret); } @@ -141,6 +146,7 @@ RegionFactory::create (Session& session, XMLNode& node, bool yn) if (r) { r->unlock_property_changes (); + map_add (r); CheckNewRegion (r); } @@ -161,6 +167,7 @@ RegionFactory::create (const SourceList& srcs, nframes_t start, nframes_t length boost::shared_ptr<AudioRegion> arp (ar); boost::shared_ptr<Region> ret (boost::static_pointer_cast<Region> (arp)); ret->unlock_property_changes (); + map_add (ret); if (announce) { CheckNewRegion (ret); } @@ -172,6 +179,7 @@ RegionFactory::create (const SourceList& srcs, nframes_t start, nframes_t length boost::shared_ptr<MidiRegion> mrp (ar); boost::shared_ptr<Region> ret (boost::static_pointer_cast<Region> (mrp)); ret->unlock_property_changes (); + map_add (ret); if (announce) { CheckNewRegion (ret); } @@ -194,11 +202,13 @@ RegionFactory::create (SourceList& srcs, const XMLNode& node) boost_debug_shared_ptr_mark_interesting (ar, "Region"); boost::shared_ptr<Region> ret (ar); ret->unlock_property_changes (); + map_add (ret); CheckNewRegion (ret); return ret; } else if (srcs[0]->type() == DataType::MIDI) { boost::shared_ptr<Region> ret (new MidiRegion (srcs, node)); ret->unlock_property_changes (); + map_add (ret); CheckNewRegion (ret); return ret; } @@ -217,6 +227,7 @@ RegionFactory::create (boost::shared_ptr<Source> src, nframes_t start, nframes_t boost_debug_shared_ptr_mark_interesting (ar, "Region"); boost::shared_ptr<Region> ret (ar); ret->unlock_property_changes (); + map_add (ret); if (announce) { CheckNewRegion (ret); } @@ -224,6 +235,7 @@ RegionFactory::create (boost::shared_ptr<Source> src, nframes_t start, nframes_t } else if ((ms = boost::dynamic_pointer_cast<MidiSource>(src)) != 0) { boost::shared_ptr<Region> ret (new MidiRegion (ms, start, length, name, layer, flags)); ret->unlock_property_changes (); + map_add (ret); if (announce) { CheckNewRegion (ret); } @@ -232,3 +244,31 @@ RegionFactory::create (boost::shared_ptr<Source> src, nframes_t start, nframes_t return boost::shared_ptr<Region>(); } + +void +RegionFactory::map_add (boost::shared_ptr<Region> r) +{ + pair<ID,boost::weak_ptr<Region> > p; + p.first = r->id(); + p.second = r; + + region_map.insert (p); +} + +boost::shared_ptr<Region> +RegionFactory::region_by_id (const PBD::ID& id) +{ + map<ID,boost::weak_ptr<Region> >::iterator i = region_map.find (id); + + if (i == region_map.end()) { + return boost::shared_ptr<Region>(); + } + + return i->second.lock(); +} + +void +RegionFactory::clear_map () +{ + region_map.clear (); +} diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 31693daff3..7b12478092 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -352,6 +352,10 @@ Session::destroy () _engine.remove_session (); + /* clear region map. it doesn't hold references, but lets just be sensible here */ + + RegionFactory::clear_map (); + /* clear history so that no references to objects are held any more */ _history.clear (); diff --git a/libs/ardour/session_command.cc b/libs/ardour/session_command.cc index 828af69901..19253cc725 100644 --- a/libs/ardour/session_command.cc +++ b/libs/ardour/session_command.cc @@ -83,32 +83,40 @@ Session::memento_command_factory(XMLNode *n) /* create command */ string obj_T = n->property ("type-name")->value(); + if (obj_T == typeid (AudioRegion).name() || obj_T == typeid (MidiRegion).name() || obj_T == typeid (Region).name()) { if (regions.count(id)) { return new MementoCommand<Region>(*regions[id], before, after); } + } else if (obj_T == typeid (AudioSource).name() || obj_T == typeid (MidiSource).name()) { if (sources.count(id)) return new MementoCommand<Source>(*sources[id], before, after); + } else if (obj_T == typeid (Location).name()) { Location* loc = _locations.get_location_by_id(id); if (loc) { return new MementoCommand<Location>(*loc, before, after); } + } else if (obj_T == typeid (Locations).name()) { return new MementoCommand<Locations>(_locations, before, after); + } else if (obj_T == typeid (TempoMap).name()) { return new MementoCommand<TempoMap>(*_tempo_map, before, after); + } else if (obj_T == typeid (Playlist).name() || obj_T == typeid (AudioPlaylist).name() || obj_T == typeid (MidiPlaylist).name()) { if (boost::shared_ptr<Playlist> pl = playlists->by_name(child->property("name")->value())) { return new MementoCommand<Playlist>(*(pl.get()), before, after); } + } else if (obj_T == typeid (Route).name() || obj_T == typeid (AudioTrack).name() || obj_T == typeid(MidiTrack).name()) { if (boost::shared_ptr<Route> r = route_by_id(id)) { return new MementoCommand<Route>(*r, before, after); } else { error << string_compose (X_("Route %1 not found in session"), id) << endmsg; } + } else if (obj_T == typeid (Evoral::Curve).name() || obj_T == typeid (AutomationList).name()) { std::map<PBD::ID, AutomationList*>::iterator i = automation_lists.find(id); if (i != automation_lists.end()) { diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index 483c9a0899..fd14094f7f 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -91,6 +91,7 @@ #include "ardour/midi_track.h" #include "ardour/named_selection.h" #include "ardour/processor.h" +#include "ardour/region_command.h" #include "ardour/region_factory.h" #include "ardour/route_group.h" #include "ardour/send.h" @@ -2944,6 +2945,16 @@ Session::restore_history (string snapshot_name) error << _("Failed to downcast MidiSource for DeltaCommand") << endmsg; } + } else if (n->name() == "RegionCommand") { + PBD::ID id (n->property ("region")->value()); + boost::shared_ptr<Region> region = RegionFactory::region_by_id (id); + + if (region) { + ut->add_command (new RegionCommand (region, *n)); + } else { + error << string_compose (_("Region command references an unknown region ID=%1"), id.to_s()) << endmsg; + } + } else { error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg; } diff --git a/libs/ardour/wscript b/libs/ardour/wscript index 33de254b36..ee9aa14850 100644 --- a/libs/ardour/wscript +++ b/libs/ardour/wscript @@ -144,6 +144,7 @@ libardour_sources = [ 'rc_configuration.cc', 'recent_sessions.cc', 'region.cc', + 'region_command.cc', 'region_factory.cc', 'resampled_source.cc', 'return.cc', |