diff --git a/src/engraving/dom/edit.cpp b/src/engraving/dom/edit.cpp index 0c0e4479802f3..5d1f06c76d48f 100644 --- a/src/engraving/dom/edit.cpp +++ b/src/engraving/dom/edit.cpp @@ -5761,18 +5761,7 @@ void Score::undoChangeVisible(EngravingItem* item, bool visible) void Score::undoAddElement(EngravingItem* element, bool addToLinkedStaves, bool ctrlModifier, EngravingItem* elementToRelink) { Staff* ostaff = element->staff(); - track_idx_t strack = muse::nidx; - if (ostaff) { - strack = ostaff->idx() * VOICES + element->track() % VOICES; - - if (mu::engraving::Excerpt* excerpt = ostaff->score()->excerpt()) { - const TracksMap& tracks = excerpt->tracksMapping(); - - if (!tracks.empty() && strack != muse::nidx) { - strack = muse::key(tracks, strack, muse::nidx); - } - } - } + track_idx_t strack = element->track(); ElementType et = element->type(); @@ -6434,16 +6423,7 @@ void Score::undoAddCR(ChordRest* cr, Measure* measure, const Fraction& tick) } Staff* ostaff = cr->staff(); - track_idx_t strack = ostaff->idx() * VOICES + cr->voice(); - // If this is on an excerpt, get actual track - if (mu::engraving::Excerpt* excerpt = ostaff->score()->excerpt()) { - if (ostaff->isVoiceVisible(cr->voice())) { - const TracksMap& tracks = excerpt->tracksMapping(); - if (!tracks.empty()) { - strack = muse::key(tracks, strack, muse::nidx); - } - } - } + track_idx_t strack = cr->track(); SegmentType segmentType = SegmentType::ChordRest; diff --git a/src/engraving/tests/parts_data/input-from-parts.mscz b/src/engraving/tests/parts_data/input-from-parts.mscz new file mode 100644 index 0000000000000..ef5ba14e42d60 Binary files /dev/null and b/src/engraving/tests/parts_data/input-from-parts.mscz differ diff --git a/src/engraving/tests/parts_tests.cpp b/src/engraving/tests/parts_tests.cpp index cd25f7d709d0c..af8d317025942 100644 --- a/src/engraving/tests/parts_tests.cpp +++ b/src/engraving/tests/parts_tests.cpp @@ -1327,6 +1327,77 @@ TEST_F(Engraving_PartsTests, partVisibleTracks) { PARTS_DATA_DIR + u"part-visible-tracks-score-ref.mscx")); } +TEST_F(Engraving_PartsTests, inputFromParts) { + bool useRead302 = MScore::useRead302InTestMode; + MScore::useRead302InTestMode = false; + + // Enter notes *in parts* and check that they are correctly cloned to the score. + + Score* score = ScoreRW::readScore(PARTS_DATA_DIR + u"input-from-parts.mscz"); + EXPECT_TRUE(score); + staff_idx_t fluteStaff = 0; + staff_idx_t oboeStaff = 1; + staff_idx_t clarinetStaff = 2; + staff_idx_t bassoonStaff = 3; + + Score* flutePart = nullptr; + Score* oboePart = nullptr; + Score* clarinetPart = nullptr; + Score* bassoonPart = nullptr; + for (Score* part : score->scoreList()) { + String partName = part->name(); + if (partName == u"Flute") { + flutePart = part; + } else if (partName == u"Oboe") { + oboePart = part; + } else if (partName == u"Clarinet in B♭") { + clarinetPart = part; + } else if (partName == u"Bassoon") { + bassoonPart = part; + } + } + EXPECT_TRUE(flutePart && oboePart && clarinetPart && bassoonPart); + + track_idx_t voice = 3; + Segment* partSegment = flutePart->firstMeasure()->findFirstR(SegmentType::ChordRest, Fraction(0, 1)); + EXPECT_TRUE(partSegment); + flutePart->setNoteRest(partSegment, voice, NoteVal(60), Fraction(1, 1)); + Segment* scoreSegment = score->tick2segment(partSegment->tick(), true, SegmentType::ChordRest); + EXPECT_TRUE(scoreSegment); + Chord* chord = toChord(scoreSegment->elementAt(staff2track(fluteStaff) + voice)); + EXPECT_TRUE(chord); + + voice = 2; + partSegment = oboePart->firstMeasure()->nextMeasure()->findFirstR(SegmentType::ChordRest, Fraction(0, 1)); + EXPECT_TRUE(partSegment); + oboePart->setNoteRest(partSegment, voice, NoteVal(60), Fraction(1, 1)); + scoreSegment = score->tick2segment(partSegment->tick(), true, SegmentType::ChordRest); + EXPECT_TRUE(scoreSegment); + chord = toChord(scoreSegment->elementAt(staff2track(oboeStaff) + voice)); + EXPECT_TRUE(chord); + + voice = 1; + partSegment = clarinetPart->firstMeasure()->nextMeasure()->nextMeasure()->findFirstR(SegmentType::ChordRest, Fraction(0, 1)); + EXPECT_TRUE(partSegment); + clarinetPart->setNoteRest(partSegment, voice, NoteVal(60), Fraction(1, 1)); + scoreSegment = score->tick2segment(partSegment->tick(), true, SegmentType::ChordRest); + EXPECT_TRUE(scoreSegment); + chord = toChord(scoreSegment->elementAt(staff2track(clarinetStaff) + voice)); + EXPECT_TRUE(chord); + + voice = 0; + partSegment = bassoonPart->firstMeasure()->nextMeasure()->nextMeasure()->nextMeasure()->findFirstR(SegmentType::ChordRest, Fraction(0, + 1)); + EXPECT_TRUE(partSegment); + bassoonPart->setNoteRest(partSegment, voice, NoteVal(60), Fraction(1, 1)); + scoreSegment = score->tick2segment(partSegment->tick(), true, SegmentType::ChordRest); + EXPECT_TRUE(scoreSegment); + chord = toChord(scoreSegment->elementAt(staff2track(bassoonStaff) + voice)); + EXPECT_TRUE(chord); + + MScore::useRead302InTestMode = useRead302; +} + //--------------------------------------------------------- // staffStyles //---------------------------------------------------------