From 3a8bdf1fc4a433ac8ef373f5175f2fa5462dc401 Mon Sep 17 00:00:00 2001 From: Matt McClinch Date: Sun, 21 Jun 2020 13:41:43 -0400 Subject: [PATCH] Fix #306917: Crash on tie in score with parts Resolves: https://musescore.org/en/node/306917. Apply the same method from https:://github.com/musescore/MuseScore/pull/6049 in undoAddElement() for determining the tracks in which to place new elements. --- libmscore/edit.cpp | 50 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/libmscore/edit.cpp b/libmscore/edit.cpp index 36a421675d0bf..d988a9df8fcae 100644 --- a/libmscore/edit.cpp +++ b/libmscore/edit.cpp @@ -4532,17 +4532,48 @@ void Score::undoAddElement(Element* element) return; } + // 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; + for (Staff* staff : ostaff->staffList()) { Score* score = staff->score(); int staffIdx = staff->idx(); QList tr; - if ((strack & ~3) != staffIdx) // linked staff ? - tr.append(staffIdx * VOICES + (strack % VOICES)); - else if (staff->score()->excerpt() && strack > -1) - tr = staff->score()->excerpt()->tracks().values(strack); - else - tr.append(strack); + if (!staff->score()->excerpt()) { + // On masterScore. + int track = staff->idx() * VOICES + (strack % VOICES); + tr.append(track); + } + else { + QMultiMap mapping = staff->score()->excerpt()->tracks(); + if (mapping.isEmpty()) { + // This can happen during reading the score and there is + // no Tracklist tag specified. + // TODO solve this in read301.cpp. + tr.append(strack); + } + else { + for (int track : mapping.values(strack)) { + // linkedPart : linked staves within same part/instrument. + // linkedScore: linked staves over different scores via excerpts. + const bool linkedPart = linked && (staff != ostaff) && (staff->score() == ostaff->score()); + const bool linkedScore = linked && (staff != ostaff) && (staff->score() != ostaff->score()); + if (linkedPart && !linkedScore) { + tr.append(staff->idx() * VOICES + mapping.value(track)); + } + else if (!linkedPart && linkedScore) { + if ((track >> 2) != staffIdx) + track += (staffIdx - (track >> 2)) * VOICES; + tr.append(track); + } + else { + tr.append(track); + } + } + } + } + // Some elements in voice 1 of a staff should be copied to every track which has a linked voice in this staff @@ -4565,13 +4596,7 @@ void Score::undoAddElement(Element* element) tr.append(staffIdx * VOICES); } - int it = 0; for (int ntrack : tr) { - if ((ntrack & ~3) != staffIdx * VOICES) { - it++; - continue; - } - Element* ne; if (staff == ostaff) ne = element; @@ -4880,7 +4905,6 @@ void Score::undoAddElement(Element* element) } else qWarning("undoAddElement: unhandled: <%s>", element->name()); - it++; } } }