From 371be41d81932d6c49029b2d1a43b7f9a9e45cce Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 23 May 2011 11:49:46 +0000 Subject: uncombine now pays attention to trims + moves done with the compound region, and applies them as necessary to the constituent regions before placing them back in the track git-svn-id: svn://localhost/ardour2/branches/3.0@9573 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/ardour/playlist.cc | 98 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 94 insertions(+), 4 deletions(-) (limited to 'libs/ardour') diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc index 85935d4377..57b919f8ae 100644 --- a/libs/ardour/playlist.cc +++ b/libs/ardour/playlist.cc @@ -3187,7 +3187,7 @@ Playlist::combine (const RegionList& r, const std::string& name) /* make position relative to zero */ pl->add_region (copied_region, original_region->position() - earliest_position); - + /* use the maximum number of channels for any region */ channels = max (channels, original_region->n_channels()); @@ -3254,17 +3254,107 @@ Playlist::uncombine (boost::shared_ptr target) pl = pls->playlist(); + framepos_t adjusted_start; + framepos_t adjusted_end; + + /* the leftmost (earliest) edge of the compound region + starts at zero in its source, or larger if it + has been trimmed or content-scrolled. + + the rightmost (latest) edge of the compound region + relative to its source is the starting point plus + the length of the region. + */ + + adjusted_start = target->start(); + adjusted_end = target->start() + target->length(); + // (2) get all the original regions const RegionList& rl (pl->region_list().rlist()); - RegionFactory::CompoundAssociations& cassocs (RegionFactory::compound_associations()); + frameoffset_t move_offset = 0; for (RegionList::const_iterator i = rl.begin(); i != rl.end(); ++i) { + + boost::shared_ptr current (*i); + + RegionFactory::CompoundAssociations::iterator ca = cassocs.find (*i); - if (ca != cassocs.end()) { - originals.push_back (ca->second); + + if (ca == cassocs.end()) { + continue; + } + + boost::shared_ptr original (ca->second); + bool modified_region; + + if (i == rl.begin()) { + move_offset = (target->position() - original->position()) - target->start(); + } + + /* check to see how the original region (in the + * playlist before compounding occured) overlaps + * with the new state of the compound region. + */ + + original->clear_changes (); + modified_region = false; + + switch (original->coverage (adjusted_start, adjusted_end)) { + case OverlapNone: + /* original region does not cover any part + of the current state of the compound region + */ + continue; + + case OverlapInternal: + /* overlap is just a small piece inside the + * original so trim both ends + */ + original->trim_to (adjusted_start, adjusted_end - adjusted_start, this); + modified_region = true; + break; + + case OverlapExternal: + /* overlap fully covers original, so leave it + as is + */ + break; + + case OverlapEnd: + /* overlap starts within but covers end, + so trim the front of the region + */ + original->trim_front (adjusted_start, this); + modified_region = true; + break; + + case OverlapStart: + /* overlap covers start but ends within, so + * trim the end of the region. + */ + original->trim_end (adjusted_end, this); + modified_region = true; + break; + } + + if (move_offset) { + /* fix the position to match any movement of the compound region. + */ + original->set_position (original->position() + move_offset, this); + modified_region = true; + } + + if (modified_region) { + _session.add_command (new StatefulDiffCommand (original)); } + + /* and add to the list of regions waiting to be + * re-inserted + */ + + originals.push_back (original); } in_partition = true; -- cgit v1.2.3