Skip to content

Commit

Permalink
Manually merged #6116 to master
Browse files Browse the repository at this point in the history
Fix #305750 - Nested tuplets in linked staves lead to corruption
  • Loading branch information
anatoly-os committed Jul 23, 2020
1 parent de74c61 commit 0ee07d9
Showing 1 changed file with 31 additions and 63 deletions.
94 changes: 31 additions & 63 deletions libmscore/edit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5077,7 +5077,7 @@ void Score::undoAddCR(ChordRest* cr, Measure* measure, const Fraction& tick)

SegmentType segmentType = SegmentType::ChordRest;

Tuplet* t = cr->tuplet();
Tuplet* crTuplet = cr->tuplet();

// For linked staves the length of staffList is always > 1 since the list contains the staff itself too!
const bool linked = ostaff->staffList().length() > 1;
Expand Down Expand Up @@ -5147,73 +5147,41 @@ void Score::undoAddCR(ChordRest* cr, Measure* measure, const Fraction& tick)
}
}
#endif
if (t) {
if (staff != ostaff) {
Tuplet* nt = 0;
if (t->elements().empty() || t->elements().front() == cr) {
for (ScoreElement* e : t->linkList()) {
Tuplet* nt1 = toTuplet(e);
if (nt1 == t) {
continue;
}
if (nt1->score() == score && nt1->track() == newcr->track()) {
nt = nt1;
break;
}
}
if (!nt) {
nt = toTuplet(t->linkedClone());
nt->setTuplet(0);
nt->setScore(score);
nt->setTrack(newcr->track());
}

Tuplet* t2 = t;
Tuplet* nt2 = nt;
while (t2->tuplet()) {
Tuplet* t3 = t2->tuplet();
Tuplet* nt3 = 0;

for (auto i : t3->linkList()) {
Tuplet* tt = toTuplet(i);
if (tt != t3 && tt->score() == score && tt->track() == t2->track()) {
nt3 = tt;
break;
}
}
if (nt3 == 0) {
nt3 = toTuplet(t3->linkedClone());
nt3->setScore(score);
nt3->setTrack(nt2->track());
}
nt3->add(nt2);
nt2->setTuplet(nt3);

t2 = t3;
nt2 = nt3;
}
} else {
const LinkedElements* le = t->links();
// search the linked tuplet
if (le) {
for (ScoreElement* ee : *le) {
Element* e = static_cast<Element*>(ee);
if (e->score() == score && e->track() == ntrack) {
nt = toTuplet(e);
break;
}
}
}
if (nt == 0) {
qWarning("linked tuplet not found");
if (crTuplet && staff != ostaff) {
// In case of nested tuplets, get the parent tuplet.
Tuplet* parTuplet { nullptr };
if (crTuplet->tuplet()) {
// Look for a tuplet, linked to the parent tuplet of crTuplet but
// which is on the same staff as the new ChordRest.
for (auto e : crTuplet->tuplet()->linkList()) {
Tuplet* t = toTuplet(e);
if (t->staff() == newcr->staff()) {
parTuplet = t;
break;
}
}
}

if (nt) {
newcr->setTuplet(nt);
nt->setParent(newcr->measure());
// Look for a tuplet linked to crTuplet but is on the same staff as
// the new ChordRest. Create a new tuplet if not found.
Tuplet* newTuplet { nullptr };
for (auto e : crTuplet->linkList()) {
Tuplet* t = toTuplet(e);
if (t->staff() == newcr->staff()) {
newTuplet = t;
break;
}
}

if (!newTuplet) {
newTuplet = toTuplet(crTuplet->linkedClone());
newTuplet->setTuplet(parTuplet);
newTuplet->setScore(score);
newTuplet->setTrack(newcr->track());
newTuplet->setParent(m);
}

newcr->setTuplet(newTuplet);
}

if (newcr->isRest() && (toRest(newcr)->isGap()) && !(toRest(newcr)->track() % VOICES)) {
Expand Down

0 comments on commit 0ee07d9

Please sign in to comment.