fix #73051: editing spanner length with multiple voices
This commit is contained in:
parent
ca2e6e97aa
commit
4ea940f564
3 changed files with 22 additions and 17 deletions
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue