From 363ac18bfbd2b90334895c1e274ec8c12b29ec43 Mon Sep 17 00:00:00 2001 From: Calum Matheson Date: Fri, 27 Sep 2024 17:35:15 +0100 Subject: [PATCH] Fix voice too long corruption --- src/engraving/dom/noteentry.cpp | 11 +++++++++++ src/engraving/dom/segment.cpp | 14 +++++++++++--- src/engraving/dom/segment.h | 2 +- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/engraving/dom/noteentry.cpp b/src/engraving/dom/noteentry.cpp index e3f14f763e167..feaac94e13017 100644 --- a/src/engraving/dom/noteentry.cpp +++ b/src/engraving/dom/noteentry.cpp @@ -450,6 +450,17 @@ Ret Score::putNote(const Position& p, bool replace) ChordRest* cr = m_is.cr(); + // If there's an overlapping ChordRest at the current input position, shorten it... + if (!cr) { + ChordRest* prevCr = m_is.segment()->nextChordRest(m_is.track(), /*backwards*/ true, /*stopAtMeasureBoundary*/ true); + if (prevCr && prevCr->endTick() > m_is.tick()) { + const Fraction overlapDuration = prevCr->endTick() - m_is.tick(); + const InputState inputStateToRestore = m_is; // because changeCRlen will alter the input state + changeCRlen(prevCr, prevCr->ticks() - overlapDuration); + m_is = inputStateToRestore; + } + } + auto checkTied = [&](){ if (!cr || !cr->isChord()) { return false; diff --git a/src/engraving/dom/segment.cpp b/src/engraving/dom/segment.cpp index 45b150802ceff..723f45630d5c4 100644 --- a/src/engraving/dom/segment.cpp +++ b/src/engraving/dom/segment.cpp @@ -585,15 +585,23 @@ Segment* Segment::nextCR(track_idx_t track, bool sameStaff) const // get the next ChordRest, start at this segment //--------------------------------------------------------- -ChordRest* Segment::nextChordRest(track_idx_t track, bool backwards) const +ChordRest* Segment::nextChordRest(track_idx_t track, bool backwards, bool stopAtMeasureBoundary) const { - for (const Segment* seg = this; seg; seg = backwards ? seg->prev1() : seg->next1()) { + const Segment* seg = this; + while (seg) { EngravingItem* el = seg->element(track); if (el && el->isChordRest()) { return toChordRest(el); } + + if (backwards) { + seg = stopAtMeasureBoundary ? seg->prev() : seg->prev1(); + continue; + } + + seg = stopAtMeasureBoundary ? seg->next() : seg->next1(); } - return 0; + return nullptr; } EngravingItem* Segment::element(track_idx_t track) const diff --git a/src/engraving/dom/segment.h b/src/engraving/dom/segment.h index ceb15329a5558..0d679055d7c87 100644 --- a/src/engraving/dom/segment.h +++ b/src/engraving/dom/segment.h @@ -138,7 +138,7 @@ class Segment final : public EngravingItem Segment* nextCR(track_idx_t track = muse::nidx, bool sameStaff = false) const; - ChordRest* nextChordRest(track_idx_t track, bool backwards = false) const; + ChordRest* nextChordRest(track_idx_t track, bool backwards = false, bool stopAtMeasureBoundary = false) const; EngravingItem* element(track_idx_t track) const;