fix #73051: editing spanner length with multiple voices

This commit is contained in:
Marc Sabatella 2015-08-12 12:07:29 -06:00
parent ca2e6e97aa
commit 4ea940f564
3 changed files with 22 additions and 17 deletions

View file

@ -3584,36 +3584,39 @@ ChordRest* Score::findCR(int tick, int track) const
//---------------------------------------------------------
// findCRinStaff
// find chord/rest <= tick in staff
// prefer shortest duration (so it does not overlap next chordrest segment)
// find last chord/rest on staff that ends before tick
//---------------------------------------------------------
ChordRest* Score::findCRinStaff(int tick, int track) const
ChordRest* Score::findCRinStaff(int tick, int staffIdx) const
{
Measure* m = tick2measureMM(tick);
int ptick = tick - 1;
Measure* m = tick2measureMM(ptick);
if (!m) {
qDebug("findCRinStaff: no measure for tick %d", tick);
qDebug("findCRinStaff: no measure for tick %d", ptick);
return nullptr;
}
// attach to first rest all spanner when mmRest
if (m->isMMRest())
tick = m->tick();
ptick = m->tick();
Segment* s = m->first(Segment::Type::ChordRest);
int strack = (track / VOICES) * VOICES;
int strack = staffIdx * VOICES;
int etrack = strack + VOICES;
int actualTrack = strack;
int lastTick = -1;
for (Segment* ns = s; ; ns = ns->next(Segment::Type::ChordRest)) {
if (ns == 0 || ns->tick() > tick)
if (ns == 0 || ns->tick() > ptick)
break;
// found a segment; now find shortest chordrest on this staff (if any)
ChordRest* shortestCR = 0;
// found a segment; now find longest cr on this staff that does not overlap tick
for (int t = strack; t < etrack; ++t) {
ChordRest* cr = static_cast<ChordRest*>(ns->element(t));
if (cr && (!shortestCR || cr->actualTicks() < shortestCR->actualTicks())) {
shortestCR = cr;
s = ns;
actualTrack = t;
if (cr) {
int endTick = cr->tick() + cr->actualTicks();
if (endTick >= lastTick && endTick <= tick) {
s = ns;
actualTrack = t;
lastTick = endTick;
}
}
}
}

View file

@ -1039,7 +1039,7 @@ class Score : public QObject {
Hairpin* addHairpin(bool crescendo, int tickStart, int tickEnd, int track);
ChordRest* findCR(int tick, int track) const;
ChordRest* findCRinStaff(int tick, int track) const;
ChordRest* findCRinStaff(int tick, int staffIdx) const;
void layoutSpanner();
void insertTime(int tickPos, int tickLen);

View file

@ -534,13 +534,15 @@ void Spanner::computeEndElement()
{
switch (_anchor) {
case Anchor::SEGMENT: {
_endElement = score()->findCRinStaff(tick2() - 1, track2());
// find last cr on this staff that ends before tick2
_endElement = score()->findCRinStaff(tick2(), track2() / VOICES);
if (!_endElement) {
qDebug("%s no end element for tick %d", name(), tick2());
return;
}
if (!endCR()->measure()->isMMRest()) {
int nticks = endCR()->tick() + endCR()->actualTicks() - _tick;
ChordRest* cr = endCR();
int nticks = cr->tick() + cr->actualTicks() - _tick;
if (_ticks != nticks) {
qDebug("%s ticks changed, %d -> %d", name(), _ticks, nticks);
setTicks(nticks);