various changes related to tempo map copy/cut/paste section

Tempo map is currently still excluded from the editor operation
This commit is contained in:
Paul Davis 2023-08-27 22:51:24 -06:00
parent 2e08ff01f5
commit a5055a2227
2 changed files with 82 additions and 31 deletions

View File

@ -7304,23 +7304,46 @@ Session::cut_copy_section (timepos_t const& start, timepos_t const& end, timepos
XMLNode &after = _locations->get_state();
add_command (new MementoCommand<Locations> (*_locations, &before, &after));
}
#if 0
#if 0 // TODO - enable once tempo-map cut/copy/paste works
TempoMap::WritableSharedPtr wmap = TempoMap::write_copy ();
TempoMapCutBuffer* tmcb;
if (copy) {
tmcb = wmap->copy (start, end);
} else {
tmcb = wmap->cut (start, end, true);
XMLNode& tm_before (wmap->get_state());
switch (op) {
case CopyPasteSection:
if ((tmcb = wmap->copy (start, end))) {
tmcb->dump (std::cerr);
wmap->paste (*tmcb, to, true);
}
break;
case CutPasteSection:
if ((tmcb = wmap->cut (start, end, true))) {
tmcb->dump (std::cerr);
wmap->paste (*tmcb, to, false);
}
break;
default:
tmcb = nullptr;
break;
}
if (tmcb) {
TempoMap::update (wmap);
delete tmcb;
delete &tm_before;
XMLNode& tm_after (wmap->get_state());
std::cerr << "Saving tmap state as part of rev cmd\n";
add_command (new MementoCommand<TempoMap> (*wmap.get(), &tm_before, &tm_after));
}
wmap->paste (*tmcb, to, !copy);
TempoMap::update (wmap);
delete tmcb;
#endif
if (!abort_empty_reversible_command ()) {
commit_reversible_command ();
return;
}
commit_reversible_command ();
}
void

View File

@ -866,6 +866,10 @@ TempoMap::copy ( timepos_t const & start, timepos_t const & end)
TempoMapCutBuffer*
TempoMap::cut_copy (timepos_t const & start, timepos_t const & end, bool copy, bool ripple)
{
if (n_tempos() == 1 && n_meters() == 1) {
return nullptr;
}
TempoMetric sm (metric_at (start));
TempoMetric em (metric_at (end));
timecnt_t dur = start.distance (end);
@ -977,12 +981,22 @@ TempoMap::cut_copy (timepos_t const & start, timepos_t const & end, bool copy, b
void
TempoMap::paste (TempoMapCutBuffer const & cb, timepos_t const & position, bool ripple)
{
if (cb.empty()) {
std::cerr << "nothing to paste\n";
return;
}
std::cerr << "tm paste, ripple " << ripple << std::endl;
if (ripple) {
shift (position, cb.duration());
}
bool replaced_ignored;
const timepos_t end_position = position + cb.duration();
Tempo end_tempo = tempo_at (end_position);
Meter end_meter = meter_at (end_position);
/* iterate over _points since they are already in sclock order, and we
* won't need to post-sort the way we would if we handled tempos,
* meters, bartimes separately.
@ -990,19 +1004,26 @@ TempoMap::paste (TempoMapCutBuffer const & cb, timepos_t const & position, bool
BBT_Time pos_bbt = bbt_at (position);
Beats pos_beats = quarters_at (position);
bool ignored;
Tempo const * st = cb.start_tempo();
if (st) {
TempoPoint *ntp = new TempoPoint (*this, *st, position.superclocks(), pos_beats, pos_bbt);
core_add_tempo (ntp, replaced_ignored);
core_add_point (ntp);
}
Meter const * mt = cb.start_meter();
if (mt) {
MeterPoint *ntp = new MeterPoint (*this, *mt, position.superclocks(), pos_beats, pos_bbt);
core_add_meter (ntp, replaced_ignored);
core_add_point (ntp);
if (!st && !mt) {
MusicTimePoint* mtp = new MusicTimePoint (*this, position.superclocks(), pos_beats, pos_bbt, tempo_at (position), meter_at (position), _("paste start"));
core_add_bartime (mtp, ignored);
core_add_point (mtp);
} else {
if (st) {
TempoPoint *ntp = new TempoPoint (*this, *st, position.superclocks(), pos_beats, pos_bbt);
core_add_tempo (ntp, replaced_ignored);
core_add_point (ntp);
}
if (mt) {
MeterPoint *ntp = new MeterPoint (*this, *mt, position.superclocks(), pos_beats, pos_bbt);
core_add_meter (ntp, replaced_ignored);
core_add_point (ntp);
}
}
for (auto const & p : cb.points()) {
@ -1030,23 +1051,28 @@ TempoMap::paste (TempoMapCutBuffer const & cb, timepos_t const & position, bool
}
}
const timepos_t end_position = position + cb.duration();
pos_bbt = bbt_at (end_position);
pos_beats = quarters_at (end_position);
st = cb.end_tempo();
if (st) {
TempoPoint *ntp = new TempoPoint (*this, *st, end_position.superclocks(), pos_beats, pos_bbt);
core_add_tempo (ntp, replaced_ignored);
core_add_point (ntp);
}
mt = cb.end_meter();
if (mt) {
MeterPoint *ntp = new MeterPoint (*this, *mt, end_position.superclocks(), pos_beats, pos_bbt);
core_add_meter (ntp, replaced_ignored);
core_add_point (ntp);
}
if (!st && !mt) {
MusicTimePoint* mtp = new MusicTimePoint (*this, end_position.superclocks(), pos_beats, pos_bbt, end_tempo, end_meter, _("paste end"));
core_add_bartime (mtp, ignored);
core_add_point (mtp);
} else {
if (st) {
TempoPoint *ntp = new TempoPoint (*this, *st, end_position.superclocks(), pos_beats, pos_bbt);
core_add_tempo (ntp, replaced_ignored);
core_add_point (ntp);
}
if (mt) {
MeterPoint *ntp = new MeterPoint (*this, *mt, end_position.superclocks(), pos_beats, pos_bbt);
core_add_meter (ntp, replaced_ignored);
core_add_point (ntp);
}
}
}
void
@ -1073,6 +1099,8 @@ TempoMap::shift (timepos_t const & at, BBT_Offset const & offset)
{
/* for now we require BBT-based shifts to be in units of whole bars */
std::cerr << "Ripple tempo map by " << offset << std::endl;
if (std::abs (offset.bars) < 1) {
return;
}