Implement cut/paste section markers
This does not include partial ranges (selection only include either range-start or range-end). Copy/paste also remains to be done
This commit is contained in:
parent
3f15a3a402
commit
2bdf51e02d
@ -258,6 +258,8 @@ public:
|
||||
|
||||
bool clear_cue_markers (samplepos_t start, samplepos_t end);
|
||||
|
||||
void cut_copy_section (timepos_t const& start, timepos_t const& end, timepos_t const& to, bool const copy);
|
||||
|
||||
void ripple (timepos_t const & at, timecnt_t const & distance, bool include_locked, bool notify);
|
||||
|
||||
XMLNode& get_state () const;
|
||||
|
@ -1680,6 +1680,87 @@ Locations::ripple (timepos_t const & at, timecnt_t const & distance, bool includ
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Locations::cut_copy_section (timepos_t const& start, timepos_t const& end, timepos_t const& to, bool const copy)
|
||||
{
|
||||
LocationList ll;
|
||||
|
||||
{
|
||||
Glib::Threads::RWLock::WriterLock lm (_lock);
|
||||
ll = locations;
|
||||
}
|
||||
|
||||
for (auto const& i : ll) {
|
||||
if (i->is_session_range () || i->is_auto_punch () || i->is_auto_loop ()) {
|
||||
continue;
|
||||
}
|
||||
if (i->locked ()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!i->is_mark ()) {
|
||||
if (i->start () >= start && i->end () <= end) {
|
||||
/* range is inside the selction, process it */
|
||||
} else if (i->start () < start && i->end () < start) {
|
||||
/* range is entirely outside the selection, possible ripple it */
|
||||
} else if (i->start () >= end && i->end () >= end) {
|
||||
/* range is entirely outside the selection, possible ripple it */
|
||||
} else {
|
||||
// TODO - How do we handle ranges that intersect start/end ?
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!copy) {
|
||||
timecnt_t distance = timecnt_t (i->start ().time_domain ());
|
||||
|
||||
if (i->start () < start) {
|
||||
/* Not affected, unless paste-point `to` is earlier,
|
||||
* in which case we need to make space there
|
||||
*/
|
||||
if (i->start () >= to) {
|
||||
distance = start.distance(end);
|
||||
}
|
||||
}
|
||||
else if (i->start () >= end) {
|
||||
/* data before this mark is "cut", so move it towards 0, unless
|
||||
* the whole cut/paste operation is earlier, in which case this mark
|
||||
* is not affected.
|
||||
*/
|
||||
if (i->start () <= to + start.distance(end)) {
|
||||
distance = end.distance(start);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* process cut/paste */
|
||||
distance = start.distance (to);
|
||||
}
|
||||
|
||||
|
||||
if (i->is_mark ()) {
|
||||
i->set_start (i->start () + distance);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* process range-end, by default use same distance as i->start
|
||||
* to retain the range length, but additionally consider the following.
|
||||
*/
|
||||
timecnt_t dist_end = distance;
|
||||
if (i->end () >= end) {
|
||||
if (i->end () > to + start.distance(end)) {
|
||||
/* paste inside range, extend range: keep range end */
|
||||
dist_end = timecnt_t (i->end ().time_domain ());
|
||||
}
|
||||
}
|
||||
|
||||
i->set (i->start () + distance, i->end () + dist_end);
|
||||
|
||||
} else {
|
||||
// TODO Copy/Paste: add new markers, disambiugate names
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Locations::clear_cue_markers (samplepos_t start, samplepos_t end)
|
||||
{
|
||||
|
@ -7206,7 +7206,6 @@ Session::cut_copy_section (timepos_t const& start, timepos_t const& end, timepos
|
||||
pl->clear_owned_changes ();
|
||||
|
||||
std::shared_ptr<Playlist> p = copy ? pl->copy (ltr) : pl->cut (ltr);
|
||||
// TODO copy interpolated MIDI events
|
||||
if (!copy) {
|
||||
pl->ripple (start, end.distance(start), NULL);
|
||||
}
|
||||
@ -7230,11 +7229,19 @@ Session::cut_copy_section (timepos_t const& start, timepos_t const& end, timepos
|
||||
Config->set_automation_follows_regions (automation_follows);
|
||||
}
|
||||
|
||||
/* automation */
|
||||
for (auto& r : *(routes.reader())) {
|
||||
r->cut_copy_section (start, end, to, copy);
|
||||
}
|
||||
|
||||
// TODO: update ranges and Tempo-Map
|
||||
{
|
||||
XMLNode &before = _locations->get_state();
|
||||
_locations->cut_copy_section (start, end, to, copy);
|
||||
XMLNode &after = _locations->get_state();
|
||||
add_command (new MementoCommand<Locations> (*_locations, &before, &after));
|
||||
}
|
||||
|
||||
// TODO: update Tempo-Map
|
||||
|
||||
if (!abort_empty_reversible_command ()) {
|
||||
commit_reversible_command ();
|
||||
|
Loading…
Reference in New Issue
Block a user