From eaea0793c78cdd31d91ba65d70838f8f9a46ee42 Mon Sep 17 00:00:00 2001 From: James Mizen Date: Tue, 9 Sep 2025 10:00:23 +0100 Subject: [PATCH 01/13] Merge pull request #29751 from mike-spa/lyricsLinesVSRightMargin Improved spacing of lyrics lines against right margin --- .../rendering/score/horizontalspacing.cpp | 26 ++++++++++++++---- .../rendering/score/horizontalspacing.h | 2 +- vtest/scores/lyrics-30.mscz | Bin 0 -> 22442 bytes 3 files changed, 22 insertions(+), 6 deletions(-) create mode 100644 vtest/scores/lyrics-30.mscz diff --git a/src/engraving/rendering/score/horizontalspacing.cpp b/src/engraving/rendering/score/horizontalspacing.cpp index c25536877f934..b926a5b62c46b 100644 --- a/src/engraving/rendering/score/horizontalspacing.cpp +++ b/src/engraving/rendering/score/horizontalspacing.cpp @@ -309,7 +309,7 @@ std::vector HorizontalSpacing::spaceSegments } if (ctx.systemIsFull) { - checkLyricsAgainstRightMargin(placedSegments); + checkLyricsAgainstRightMargin(placedSegments, ctx); checkLargeTimeSigAgainstRightMargin(placedSegments); } @@ -473,13 +473,20 @@ void HorizontalSpacing::checkLyricsAgainstLeftMargin(Segment* segment, double& x } } -void HorizontalSpacing::checkLyricsAgainstRightMargin(std::vector& segPositions) +void HorizontalSpacing::checkLyricsAgainstRightMargin(std::vector& segPositions, const HorizontalSpacingContext& ctx) { + const double systemEdge = segPositions.back().xPosInSystemCoords + segPositions.back().segment->minRight(); + const MStyle& style = ctx.system->style(); + const bool lyricsDashForce = style.styleB(Sid::lyricsDashForce); + const bool lyricsMelismaForce = style.styleB(Sid::lyricsMelismaForce); + const double minSpaceForDash = lyricsDashForce ? style.styleMM(Sid::lyricsDashPad) + style.styleMM(Sid::lyricsDashMinLength) + + style.styleMM(Sid::lineEndToBarlineDistance) + segPositions.back().segment->minRight() : 0.0; + const double minSpaceForMelisma = lyricsMelismaForce ? style.styleMM(Sid::lyricsMelismaPad) + style.styleMM(Sid::lyricsMelismaMinLength) + + style.styleMM(Sid::lineEndToBarlineDistance) + segPositions.back().segment->minRight() : 0.0; + int chordRestSegmentsCount = 0; for (size_t i = segPositions.size(); i > 1; --i) { - double systemEdge = segPositions.back().xPosInSystemCoords + segPositions.back().segment->minRight(); - SegmentPosition& segPos = segPositions[i - 1]; double x = segPos.xPosInSystemCoords; Segment* seg = segPos.segment; @@ -495,7 +502,16 @@ void HorizontalSpacing::checkLyricsAgainstRightMargin(std::vectorshapes()) { for (const ShapeElement& shapeEl : shape.elements()) { if (shapeEl.item() && shapeEl.item()->isLyrics()) { - xMaxLyrics = std::max(xMaxLyrics, x + shapeEl.right()); + const Lyrics* lyrics = toLyrics(shapeEl.item()); + bool hasMelisma = lyrics->separator() && lyrics->separator()->isEndMelisma(); + bool hasDash = lyrics->syllabic() == LyricsSyllabic::BEGIN || lyrics->syllabic() == LyricsSyllabic::MIDDLE; + double rightEdge = x + shapeEl.right(); + if (hasDash) { + rightEdge += minSpaceForDash; + } else if (hasMelisma) { + rightEdge += minSpaceForMelisma; + } + xMaxLyrics = std::max(xMaxLyrics, rightEdge); } } } diff --git a/src/engraving/rendering/score/horizontalspacing.h b/src/engraving/rendering/score/horizontalspacing.h index b556a57206b65..14a7a4222ec00 100644 --- a/src/engraving/rendering/score/horizontalspacing.h +++ b/src/engraving/rendering/score/horizontalspacing.h @@ -112,7 +112,7 @@ class HorizontalSpacing HorizontalSpacingContext& ctx); static bool stopCheckingPreviousSegments(const SegmentPosition& prev, const SegmentPosition& curSegPos); static void checkLyricsAgainstLeftMargin(Segment* segment, double& x, HorizontalSpacingContext& ctx); - static void checkLyricsAgainstRightMargin(std::vector& segPositions); + static void checkLyricsAgainstRightMargin(std::vector& segPositions, const HorizontalSpacingContext& ctx); static double spaceLyricsAgainstBarlines(Segment* firstSeg, Segment* secondSeg, const HorizontalSpacingContext& ctx); static void checkLargeTimeSigAgainstRightMargin(std::vector& segPositions); static void moveRightAlignedSegments(std::vector& placedSegments, const HorizontalSpacingContext& ctx); diff --git a/vtest/scores/lyrics-30.mscz b/vtest/scores/lyrics-30.mscz new file mode 100644 index 0000000000000000000000000000000000000000..cd936b1795173eb921462c33a67782b8d29c5c93 GIT binary patch literal 22442 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 Date: Wed, 3 Sep 2025 12:12:48 +0200 Subject: [PATCH 02/13] Merge pull request #29625 from mike-spa/fixEnterHarmonyOnExistingFretBug Fix enter harmony on existing fret bug --- src/engraving/data/harmony_to_diagram.xml | 4 ++-- src/engraving/dom/edit.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/engraving/data/harmony_to_diagram.xml b/src/engraving/data/harmony_to_diagram.xml index b44eaaa3d3036..65e7a2745a4a2 100644 --- a/src/engraving/data/harmony_to_diagram.xml +++ b/src/engraving/data/harmony_to_diagram.xml @@ -33782,14 +33782,14 @@ circle - circle + normal circle - O[2-O][2-O]OOO + O[2-O][2-O]O[2-O]O c#m7b5/e diff --git a/src/engraving/dom/edit.cpp b/src/engraving/dom/edit.cpp index 9e17cdebddf4f..f894942561470 100644 --- a/src/engraving/dom/edit.cpp +++ b/src/engraving/dom/edit.cpp @@ -7047,7 +7047,7 @@ void Score::undoAddElement(EngravingItem* element, bool addToLinkedStaves, bool // make harmony child of fret diagram if possible if (ne->isHarmony()) { for (EngravingItem* segel : segment->annotations()) { - if (segel && segel->isFretDiagram() && segel->track() == linkedTrack) { + if (segel && segel->isFretDiagram() && segel->track() == linkedTrack && !toFretDiagram(segel)->harmony()) { segel->add(ne); break; } From 4bbe92bda11532a2d086fd573f8bbf294f9951ff Mon Sep 17 00:00:00 2001 From: Michele Spagnolo Date: Tue, 9 Sep 2025 16:53:25 +0200 Subject: [PATCH 03/13] Merge pull request #29644 from mike-spa/fixErrorOnMoveStaffAboveSOLayer Fix error on move stave above SO layer --- src/engraving/dom/staff.cpp | 7 ++++++- src/engraving/dom/staff.h | 1 + src/instrumentsscene/view/roottreeitem.cpp | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/engraving/dom/staff.cpp b/src/engraving/dom/staff.cpp index 0fb94e6a092ec..059d48a6f58e0 100644 --- a/src/engraving/dom/staff.cpp +++ b/src/engraving/dom/staff.cpp @@ -249,6 +249,11 @@ bool Staff::shouldShowMeasureNumbers() const return false; } +bool Staff::isLastOfScore() const +{ + return score()->staves().empty() ? false : score()->staves().back() == this; +} + bool Staff::isSystemObjectStaff() const { return score() && muse::contains(score()->systemObjectStaves(), const_cast(this)); @@ -256,7 +261,7 @@ bool Staff::isSystemObjectStaff() const bool Staff::hasSystemObjectsBelowBottomStaff() const { - return isSystemObjectStaff() && score()->staves().back() == this && style().styleB(Sid::systemObjectsBelowBottomStaff); + return isSystemObjectStaff() && isLastOfScore() && style().styleB(Sid::systemObjectsBelowBottomStaff); } //--------------------------------------------------------- diff --git a/src/engraving/dom/staff.h b/src/engraving/dom/staff.h index 3cbae73a04382..f884c745e082a 100644 --- a/src/engraving/dom/staff.h +++ b/src/engraving/dom/staff.h @@ -264,6 +264,7 @@ class Staff final : public EngravingItem void undoSetShowMeasureNumbers(bool show); bool shouldShowMeasureNumbers() const; + bool isLastOfScore() const; bool isSystemObjectStaff() const; bool hasSystemObjectsBelowBottomStaff() const; diff --git a/src/instrumentsscene/view/roottreeitem.cpp b/src/instrumentsscene/view/roottreeitem.cpp index 6c0454f415852..f36d048dc952c 100644 --- a/src/instrumentsscene/view/roottreeitem.cpp +++ b/src/instrumentsscene/view/roottreeitem.cpp @@ -218,7 +218,7 @@ MoveParams RootTreeItem::buildSystemObjectsMoveParams(int sourceRow, int count, if ((sourceIsSystemObjectLayer && moveUp) || (sourceIsPartLayer && moveDown)) { moveParams.moveSysObjAboveBottomStaff = true; } - } else if (sourceIsPartLayer && moveUp) { + } else if (sourceIsPartLayer && srcStaff->isLastOfScore() && moveUp) { moveParams.moveSysObjBelowBottomStaff = true; } From e86d38cbbbc149e539c57eb92005f85fdc5c3744 Mon Sep 17 00:00:00 2001 From: James Mizen Date: Thu, 4 Sep 2025 09:10:35 +0100 Subject: [PATCH 04/13] Merge pull request #29640 from mike-spa/fixCrashOnEnterHopo Fix crash on enter HOPO on grace note --- src/engraving/dom/spanner.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/engraving/dom/spanner.cpp b/src/engraving/dom/spanner.cpp index ce0be57a65def..3f469acdcb5aa 100644 --- a/src/engraving/dom/spanner.cpp +++ b/src/engraving/dom/spanner.cpp @@ -1621,12 +1621,18 @@ String SpannerSegment::formatBarsAndBeats() const endSegment = score()->lastSegment()->prev1MM(SegmentType::ChordRest); } - if (endSegment->tick() != score()->lastSegment()->prev1MM(SegmentType::ChordRest)->tick() + if (endSegment->tick() > Fraction(0, 1) + && endSegment->tick() != score()->lastSegment()->prev1MM(SegmentType::ChordRest)->tick() && spanner->type() != ElementType::SLUR + && spanner->type() != ElementType::HAMMER_ON_PULL_OFF && spanner->type() != ElementType::TIE) { endSegment = endSegment->prev1MM(SegmentType::ChordRest); } + IF_ASSERT_FAILED(endSegment) { + return EngravingItem::formatBarsAndBeats(); + } + return formatStartBarsAndBeats(spanner->startSegment()) + u' ' + formatEndBarsAndBeats(endSegment); } From 5117fb9442b054e2c78cf707dd24bccbd282bd5c Mon Sep 17 00:00:00 2001 From: James Mizen Date: Thu, 4 Sep 2025 14:55:04 +0100 Subject: [PATCH 05/13] Merge pull request #29676 from mike-spa/fixDotsOnSameFretAsBarre MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Don't remove dots outside the strings covered by the barré --- src/engraving/rendering/score/tlayout.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engraving/rendering/score/tlayout.cpp b/src/engraving/rendering/score/tlayout.cpp index 656e54db09b2a..d7599e4c7a7f5 100644 --- a/src/engraving/rendering/score/tlayout.cpp +++ b/src/engraving/rendering/score/tlayout.cpp @@ -2823,8 +2823,8 @@ void TLayout::layoutFretDiagram(const FretDiagram* item, FretDiagram::LayoutData int endString = barre.endString != -1 ? barre.endString : item->strings() - 1; int fret = i.first; bool slurStyleBarre = ctx.conf().styleB(Sid::barreAppearanceSlur); - for (int string = 0; string < item->strings(); ++string) { - if (slurStyleBarre && string >= startString && string <= endString) { + for (int string = startString; string <= endString; ++string) { + if (slurStyleBarre) { const_cast(item)->addDotForDotStyleBarre(string, fret); } else { const_cast(item)->removeDotForDotStyleBarre(string, fret); From b3bbc62172549379dbd4406ff6cd369f068367b2 Mon Sep 17 00:00:00 2001 From: Michele Spagnolo Date: Mon, 8 Sep 2025 09:21:42 +0200 Subject: [PATCH 06/13] Merge pull request #29642 from mike-spa/fixCorruptionOnModifySecondStave Fix #29454 corruption when modifying second staff --- src/notation/inotationparts.h | 1 + src/notation/internal/masternotationparts.cpp | 5 ++-- src/notation/internal/masternotationparts.h | 1 + src/notation/internal/notationparts.cpp | 23 +++++++++++++++++++ src/notation/internal/notationparts.h | 1 + 5 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/notation/inotationparts.h b/src/notation/inotationparts.h index e1f2ca62439c9..33305404bbe03 100644 --- a/src/notation/inotationparts.h +++ b/src/notation/inotationparts.h @@ -72,6 +72,7 @@ class INotationParts InsertMode mode = InsertMode::Before) = 0; virtual bool appendStaff(Staff* staff, const muse::ID& destinationPartId) = 0; + virtual bool appendStaffLinkedToMaster(Staff* staff, Staff* masterSourceStaff, const muse::ID& destinationPartId) = 0; virtual bool appendLinkedStaff(Staff* staff, const muse::ID& sourceStaffId, const muse::ID& destinationPartId) = 0; virtual void insertPart(Part* part, size_t index) = 0; diff --git a/src/notation/internal/masternotationparts.cpp b/src/notation/internal/masternotationparts.cpp index c8313a9954b85..2839f29c4dded 100644 --- a/src/notation/internal/masternotationparts.cpp +++ b/src/notation/internal/masternotationparts.cpp @@ -145,9 +145,8 @@ bool MasterNotationParts::appendStaff(Staff* staff, const ID& destinationPartId) for (const INotationPartsPtr& parts : excerptsParts()) { Staff* excerptStaff = staff->clone(); - if (parts->appendStaff(excerptStaff, destinationPartId)) { - excerptStaff->linkTo(staff); - } else { + if (!parts->appendStaffLinkedToMaster(excerptStaff, staff, destinationPartId)) { + excerptStaff->undoUnlink(); delete excerptStaff; } } diff --git a/src/notation/internal/masternotationparts.h b/src/notation/internal/masternotationparts.h index bdf080d5d2cf4..f0eec2953bc11 100644 --- a/src/notation/internal/masternotationparts.h +++ b/src/notation/internal/masternotationparts.h @@ -40,6 +40,7 @@ class MasterNotationParts : public NotationParts void removeStaves(const muse::IDList& stavesIds) override; bool appendStaff(Staff* staff, const muse::ID& destinationPartId) override; + bool appendStaffLinkedToMaster(Staff*, Staff*, const muse::ID&) override { return false; } bool appendLinkedStaff(Staff* staff, const muse::ID& sourceStaffId, const muse::ID& destinationPartId) override; void replaceInstrument(const InstrumentKey& instrumentKey, const Instrument& newInstrument, diff --git a/src/notation/internal/notationparts.cpp b/src/notation/internal/notationparts.cpp index 64b55f9060711..7cd0c8968054a 100644 --- a/src/notation/internal/notationparts.cpp +++ b/src/notation/internal/notationparts.cpp @@ -600,6 +600,29 @@ bool NotationParts::appendStaff(Staff* staff, const ID& destinationPartId) return true; } +bool NotationParts::appendStaffLinkedToMaster(Staff* staff, Staff* masterSourceStaff, const muse::ID& destinationPartId) +{ + TRACEFUNC; + + IF_ASSERT_FAILED(staff && masterSourceStaff) { + return false; + } + + Part* destinationPart = partModifiable(destinationPartId); + if (!destinationPart) { + return false; + } + + startEdit(TranslatableString("undoableAction", "Add staff")); + + doAppendStaff(staff, destinationPart, /*createRests*/ false); + score()->undo(new mu::engraving::Link(staff, masterSourceStaff)); + + mu::engraving::Excerpt::cloneStaff2(masterSourceStaff, staff, Fraction(0, 1), score()->endTick()); + + return true; +} + bool NotationParts::appendLinkedStaff(Staff* staff, const muse::ID& sourceStaffId, const muse::ID& destinationPartId) { TRACEFUNC; diff --git a/src/notation/internal/notationparts.h b/src/notation/internal/notationparts.h index 34e244cae241f..2a704c486e784 100644 --- a/src/notation/internal/notationparts.h +++ b/src/notation/internal/notationparts.h @@ -66,6 +66,7 @@ class NotationParts : public INotationParts, public muse::async::Asyncable void moveStaves(const muse::IDList& sourceStavesIds, const muse::ID& destinationStaffId, InsertMode mode = InsertMode::Before) override; bool appendStaff(Staff* staff, const muse::ID& destinationPartId) override; + bool appendStaffLinkedToMaster(Staff* staff, Staff* masterSourceStaff, const muse::ID& destinationPartId) override; bool appendLinkedStaff(Staff* staff, const muse::ID& sourceStaffId, const muse::ID& destinationPartId) override; void insertPart(Part* part, size_t index) override; From 4370a897457ae4c06eb06df869e5e2b91505fbac Mon Sep 17 00:00:00 2001 From: RomanPudashkin <67867444+RomanPudashkin@users.noreply.github.com> Date: Fri, 5 Sep 2025 10:50:29 +0300 Subject: [PATCH 07/13] Merge pull request #29684 from mike-spa/fixWrongDragOfFretDiagrams Get ChordRest segment when pasting FretDiagram, not TimeTick --- src/engraving/rw/read460/read460.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/engraving/rw/read460/read460.cpp b/src/engraving/rw/read460/read460.cpp index a2091417eb477..172283a3c4bba 100644 --- a/src/engraving/rw/read460/read460.cpp +++ b/src/engraving/rw/read460/read460.cpp @@ -617,7 +617,9 @@ bool Read460::pasteStaff(XmlReader& e, Segment* dst, staff_idx_t dstStaff, Fract Fraction tick = doScale ? (ctx.tick() - dstTick) * scale + dstTick : ctx.tick(); Measure* m = score->tick2measure(tick); - Segment* seg = m->undoGetChordRestOrTimeTickSegment(tick); + Segment* seg = el->isFretDiagram() + ? m->undoGetSegment(SegmentType::ChordRest, tick) + : m->undoGetChordRestOrTimeTickSegment(tick); el->setParent(seg); // be sure to paste the element in the destination track; From 3a0125049da212ae91c560ef2be3a1afc88c6d06 Mon Sep 17 00:00:00 2001 From: James Mizen Date: Fri, 5 Sep 2025 12:00:14 +0100 Subject: [PATCH 08/13] Merge pull request #29700 from mike-spa/fixFullBarRestHeightWithAccidental Fix full measure rest height with accidental --- src/engraving/rendering/score/restlayout.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engraving/rendering/score/restlayout.cpp b/src/engraving/rendering/score/restlayout.cpp index 33f4e7ab3c9be..94e4933d48d72 100644 --- a/src/engraving/rendering/score/restlayout.cpp +++ b/src/engraving/rendering/score/restlayout.cpp @@ -602,7 +602,7 @@ void RestLayout::checkFullMeasureRestCollisions(const System* system, LayoutCont } measureShape.remove_if([fullMeasureRest] (const ShapeElement& shapeEl) { const EngravingItem* shapeItem = shapeEl.item(); - return shapeItem && (shapeItem == fullMeasureRest || shapeItem->isBarLine()); + return shapeItem && (shapeItem == fullMeasureRest || shapeItem->isBarLine() || shapeItem->isAccidental()); }); const double spatium = fullMeasureRest->spatium(); From 71bc5b3f1e71c8f3380998d387c08ff8d3d60fdc Mon Sep 17 00:00:00 2001 From: Michele Spagnolo Date: Mon, 8 Sep 2025 09:20:07 +0200 Subject: [PATCH 09/13] Merge pull request #29624 from mike-spa/simplifyDiagramOrderingAndVisibility Simplify diagram ordering and visibility --- src/engraving/dom/box.cpp | 108 +++--------------- src/engraving/dom/box.h | 12 +- src/engraving/dom/edit.cpp | 103 +++-------------- src/engraving/dom/property.cpp | 1 - src/engraving/dom/property.h | 1 - src/engraving/rendering/score/tlayout.cpp | 7 +- src/engraving/rw/read460/tread.cpp | 2 - src/engraving/rw/write/twrite.cpp | 2 - src/engraving/tests/fretbox_tests.cpp | 7 +- .../fretframe/fretframechordlistmodel.cpp | 18 +-- 10 files changed, 49 insertions(+), 212 deletions(-) diff --git a/src/engraving/dom/box.cpp b/src/engraving/dom/box.cpp index fbdea04f6c8ec..3431ba4daa074 100644 --- a/src/engraving/dom/box.cpp +++ b/src/engraving/dom/box.cpp @@ -749,6 +749,8 @@ void FBox::init() } } + m_diagramsOrderInScore = diagramsNamesInScore; + for (size_t i = 0; i < oldDiagramsNames.size(); ++i) { String oldName = oldDiagramsNames[i]; if (!muse::contains(diagramsNamesInScore, oldName)) { @@ -766,19 +768,6 @@ void FBox::init() score()->undo(new AddFretDiagramToFretBox(newDiagram, idx)); } } - - StringList currentDiagrams; - for (EngravingItem* item : el()) { - currentDiagrams.push_back(toFretDiagram(item)->harmonyText().toLower()); - } - - if (!m_invisibleDiagrams.empty()) { - updateInvisibleDiagrams(currentDiagrams); - } - - if (!m_diagramsOrder.empty()) { - updateDiagramsOrder(currentDiagrams); - } } void FBox::add(EngravingItem* e) @@ -848,9 +837,7 @@ PropertyValue FBox::getProperty(Pid propertyId) const case Pid::RIGHT_MARGIN: return m_contentAlignmentH == AlignH::RIGHT ? VBox::getProperty(propertyId) : PropertyValue(); case Pid::FRET_FRAME_DIAGRAMS_ORDER: - return !m_diagramsOrder.empty() ? m_diagramsOrder.join(FRET_BOX_DIAGRAMS_SEPARATOR) : PropertyValue(); - case Pid::FRET_FRAME_INVISIBLE_DIAGRAMS: - return !m_invisibleDiagrams.empty() ? m_invisibleDiagrams.join(FRET_BOX_DIAGRAMS_SEPARATOR) : PropertyValue(); + return diagramsOrder().join(FRET_BOX_DIAGRAMS_SEPARATOR); default: return VBox::getProperty(propertyId); } @@ -880,10 +867,7 @@ bool FBox::setProperty(Pid propertyId, const PropertyValue& val) resetProperty(Pid::RIGHT_MARGIN); break; case Pid::FRET_FRAME_DIAGRAMS_ORDER: - m_diagramsOrder = val.value().split(FRET_BOX_DIAGRAMS_SEPARATOR); - break; - case Pid::FRET_FRAME_INVISIBLE_DIAGRAMS: - m_invisibleDiagrams = val.value().split(FRET_BOX_DIAGRAMS_SEPARATOR); + reorderElements(val.value().split(FRET_BOX_DIAGRAMS_SEPARATOR)); break; default: return VBox::setProperty(propertyId, val); @@ -907,9 +891,7 @@ PropertyValue FBox::propertyDefault(Pid propertyId) const case Pid::FRET_FRAME_H_ALIGN: return static_cast(AlignH::HCENTER); case Pid::FRET_FRAME_DIAGRAMS_ORDER: - return PropertyValue(); - case Pid::FRET_FRAME_INVISIBLE_DIAGRAMS: - return PropertyValue(); + return m_diagramsOrderInScore.join(FRET_BOX_DIAGRAMS_SEPARATOR); default: return VBox::propertyDefault(propertyId); } @@ -946,81 +928,25 @@ void FBox::undoReorderElements(const StringList& newOrder) triggerLayout(); } -ElementList FBox::orderedElements(bool includeInvisible) const +void FBox::reorderElements(const StringList& newOrder) { - ElementList elements = el(); - const StringList& diagramsOrder = this->diagramsOrder(); - if (diagramsOrder.empty()) { - return elements; - } - - std::sort(elements.begin(), elements.end(), [&diagramsOrder](const EngravingItem* a, const EngravingItem* b) { - const FretDiagram* diagramA = toFretDiagram(a); - const String diagramAHarmonyName = diagramA->harmonyText().toLower(); - - const FretDiagram* diagramB = toFretDiagram(b); - const String diagramBHarmonyName = diagramB->harmonyText().toLower(); - - auto itA = std::find(diagramsOrder.begin(), diagramsOrder.end(), diagramAHarmonyName); - auto itB = std::find(diagramsOrder.begin(), diagramsOrder.end(), diagramBHarmonyName); - - return itA < itB; + std::sort(m_el.begin(), m_el.end(), [&](EngravingItem* a, EngravingItem* b) { + String nameA = toFretDiagram(a)->harmonyText().toLower(); + String nameB = toFretDiagram(b)->harmonyText().toLower(); + auto iterA = std::find(newOrder.begin(), newOrder.end(), nameA); + auto iterB = std::find(newOrder.begin(), newOrder.end(), nameB); + return iterA < iterB; }); - - if (!includeInvisible) { - const StringList& invisibleDiagrams = this->invisibleDiagrams(); - - muse::remove_if(elements, [&invisibleDiagrams](const EngravingItem* element){ - const FretDiagram* diagram = toFretDiagram(element); - const String diagramHarmonyName = diagram->harmonyText().toLower(); - return muse::contains(invisibleDiagrams, diagramHarmonyName); - }); - } - - return elements; } -void FBox::undoSetInvisibleDiagrams(const StringList& invisibleDiagrams) +StringList FBox::diagramsOrder() const { - StringList diagrams; - for (const String& harmonyName : invisibleDiagrams) { - diagrams.push_back(harmonyName.toLower()); + StringList result; + for (EngravingItem* item : m_el) { + result.push_back(toFretDiagram(item)->harmonyText().toLower()); } - undoChangeProperty(Pid::FRET_FRAME_INVISIBLE_DIAGRAMS, diagrams.join(FRET_BOX_DIAGRAMS_SEPARATOR)); - triggerLayout(); -} - -void FBox::updateDiagramsOrder(const StringList& currentDiagrams) -{ - if (currentDiagrams == m_diagramsOrder) { - return; - } - - m_diagramsOrder.erase(std::remove_if(m_diagramsOrder.begin(), m_diagramsOrder.end(), - [&](const String& harmonyName) { return !muse::contains(currentDiagrams, harmonyName); }), - m_diagramsOrder.end()); - - String previousHarmonyName; - for (const String& harmonyName : currentDiagrams) { - if (!muse::contains(m_diagramsOrder, harmonyName)) { - size_t index = 0; - if (!previousHarmonyName.empty()) { - index = std::find(m_diagramsOrder.begin(), m_diagramsOrder.end(), previousHarmonyName) - m_diagramsOrder.begin() + 1; - } - - m_diagramsOrder.insert(m_diagramsOrder.begin() + index, harmonyName); - } - - previousHarmonyName = harmonyName; - } -} - -void FBox::updateInvisibleDiagrams(const StringList& currentDiagrams) -{ - m_invisibleDiagrams.erase(std::remove_if(m_invisibleDiagrams.begin(), m_invisibleDiagrams.end(), - [&](const String& harmonyName) { return !muse::contains(currentDiagrams, harmonyName); }), - m_invisibleDiagrams.end()); + return result; } //--------------------------------------------------------- diff --git a/src/engraving/dom/box.h b/src/engraving/dom/box.h index 56c31ef8c540e..e6a6ed1ab5758 100644 --- a/src/engraving/dom/box.h +++ b/src/engraving/dom/box.h @@ -208,19 +208,14 @@ class FBox : public VBox std::vector gripsPositions(const EditData&) const override; void undoReorderElements(const StringList& newOrder); - const StringList& diagramsOrder() const { return m_diagramsOrder; } - - void undoSetInvisibleDiagrams(const StringList& invisibleDiagrams); - const StringList& invisibleDiagrams() const { return m_invisibleDiagrams; } - - ElementList orderedElements(bool includeInvisible = false) const; + void reorderElements(const StringList& newOrder); + StringList diagramsOrder() const; bool needsRebuild() const { return m_needsRebuild; } void setNeedsRebuild(bool v) { m_needsRebuild = v; } private: - void updateDiagramsOrder(const StringList& currentDiagrams); void updateInvisibleDiagrams(const StringList& currentDiagrams); size_t computeInsertionIdx(const String& nameOfDiagramBeforeThis); @@ -234,8 +229,7 @@ class FBox : public VBox AlignH m_contentAlignmentH = AlignH::HCENTER; - StringList /*harmonyNames*/ m_diagramsOrder; - StringList /*harmonyNames*/ m_invisibleDiagrams; + StringList m_diagramsOrderInScore; }; //--------------------------------------------------------- diff --git a/src/engraving/dom/edit.cpp b/src/engraving/dom/edit.cpp index f894942561470..1a06a598789c3 100644 --- a/src/engraving/dom/edit.cpp +++ b/src/engraving/dom/edit.cpp @@ -3886,37 +3886,6 @@ void Score::cmdDeleteSelection() // so we don't try to delete them twice if they are also in selection std::set deletedSpanners; - // diagrams in the fret box must be processed first than diagrams outside the box, - // which causes the fret box to be rebuilt and all elements inside to be deleted - std::sort(el.begin(), el.end(), [&](const EngravingItem* item1, const EngravingItem* item2) { - bool inBox1 = isElementInFretBox(item1); - bool inBox2 = isElementInFretBox(item2); - - return inBox1 == inBox2 ? false : inBox1; - }); - - // if there is harmony or fret diagram outside the fret box - // then the fret box will be rebuilt and we should exclude fret box's elements - bool hasHarmonyOrFretDiagramsInFretBox = false; - bool hasHarmonyOrFretDiagramsOutFretBox = false; - for (const EngravingItem* element : el) { - if (!element->isFretDiagram() && !element->isHarmony()) { - continue; - } - - if (isElementInFretBox(element)) { - hasHarmonyOrFretDiagramsInFretBox = true; - } else { - hasHarmonyOrFretDiagramsOutFretBox = true; - } - - if (hasHarmonyOrFretDiagramsInFretBox && hasHarmonyOrFretDiagramsOutFretBox) { - break; - } - } - - bool willFretBoxBeRebuilded = hasHarmonyOrFretDiagramsInFretBox && hasHarmonyOrFretDiagramsOutFretBox; - auto selectCRAtTickAndTrack = [this, &crsSelectedAfterDeletion](Fraction tick, track_idx_t track) { ChordRest* cr = findCR(tick, track); if (cr) { @@ -3988,64 +3957,26 @@ void Score::cmdDeleteSelection() continue; } - // We can't delete elements inside fret box, instead we hide them if (e->isFretDiagram() || e->isHarmony()) { - auto excludeElementFromSelectionInfo = [this](EngravingItem* element) { - // we need to exclude elements ftom undo stack selection info, - // so that when trying to return the selection there is no crash - UndoMacro* activeCommand = undoStack()->activeCommand(); - activeCommand->excludeElementFromSelectionInfo(element); - }; - - if (willFretBoxBeRebuilded && isElementInFretBox(e)) { - excludeElementFromSelectionInfo(e); - continue; - } - - auto hideDiagramInFretBox = [&excludeElementFromSelectionInfo](FBox* fbox, EngravingItem* element){ - StringList invisibleDiagrams = fbox->invisibleDiagrams(); - const String harmonyName = element->isFretDiagram() ? toFretDiagram(element)->harmony()->harmonyName().toLower() - : toHarmony(element)->harmonyName().toLower(); - - invisibleDiagrams.push_back(harmonyName); - fbox->undoSetInvisibleDiagrams(invisibleDiagrams); - - excludeElementFromSelectionInfo(element); - }; - - if (e->isFretDiagram() && toFretDiagram(e)->isInFretBox()) { - FBox* fbox = toFBox(e->explicitParent()); - hideDiagramInFretBox(fbox, toFretDiagram(e)); - elSelectedAfterDeletion = fbox; - continue; - } else if (e->isHarmony()) { - EngravingObject* parent = toHarmony(e)->explicitParent(); - FretDiagram* fretDiagram = parent->isFretDiagram() ? toFretDiagram(parent) : nullptr; - - if (fretDiagram && fretDiagram->isInFretBox()) { - FBox* fbox = toFBox(fretDiagram->explicitParent()); - hideDiagramInFretBox(fbox, fretDiagram); - elSelectedAfterDeletion = fbox; + FBox* fbox = toFBox(e->findAncestor(ElementType::FBOX)); + if (fbox) { + // We can't delete elements inside fret box, instead we hide them + if (FretDiagram* fretDiagram = e->isFretDiagram() ? toFretDiagram(e) : toFretDiagram(e->parent())) { + fretDiagram->undoChangeProperty(Pid::VISIBLE, false); continue; } - } - } - - if (e->isFretDiagram()) { - FretDiagram* fretDiagram = toFretDiagram(e); - Harmony* harmony = fretDiagram->harmony(); - if (harmony) { - undo(new FretLinkHarmony(fretDiagram, harmony, true /* unlink */)); - elSelectedAfterDeletion = fretDiagram->segment()->findAnnotation(ElementType::HARMONY, - fretDiagram->track(), - fretDiagram->track()); - } - } - - if (e->isHarmony()) { - Harmony* harmony = toHarmony(e); - if (harmony->parentItem()->isFretDiagram()) { - elSelectedAfterDeletion = harmony->parentItem(); + } else if (e->isFretDiagram()) { + FretDiagram* fretDiagram = toFretDiagram(e); + Harmony* harmony = fretDiagram->harmony(); + if (harmony) { + undo(new FretLinkHarmony(fretDiagram, harmony, true /* unlink */)); + elSelectedAfterDeletion = harmony; + } + } else if (e->isHarmony()) { + Harmony* harmony = toHarmony(e); + if (harmony->parentItem()->isFretDiagram()) { + elSelectedAfterDeletion = harmony->parentItem(); + } } } diff --git a/src/engraving/dom/property.cpp b/src/engraving/dom/property.cpp index 6c3ee312a59c4..462ca1360d40c 100644 --- a/src/engraving/dom/property.cpp +++ b/src/engraving/dom/property.cpp @@ -148,7 +148,6 @@ static constexpr PropertyMetaData propertyList[] = { { Pid::FRET_FRAME_CHORDS_PER_ROW, false, "fretFrameChordsPerRow", P_TYPE::INT, PropertyGroup::APPEARANCE, DUMMY_QT_TR_NOOP("propertyName", "chords per row") }, { Pid::FRET_FRAME_H_ALIGN, false, "fretFrameHorizontalAlign", P_TYPE::INT, PropertyGroup::APPEARANCE, DUMMY_QT_TR_NOOP("propertyName", "horizontal alignment") }, { Pid::FRET_FRAME_DIAGRAMS_ORDER, false, "fretFrameDiagramsOrder", P_TYPE::STRING, PropertyGroup::APPEARANCE, DUMMY_QT_TR_NOOP("propertyName", "diagrams order") }, - { Pid::FRET_FRAME_INVISIBLE_DIAGRAMS, false, "fretFrameInvisibleDiagrams", P_TYPE::STRING, PropertyGroup::APPEARANCE, DUMMY_QT_TR_NOOP("propertyName", "invisible diagrams") }, { Pid::SCALE, false, "scale", P_TYPE::SCALE, PropertyGroup::APPEARANCE, DUMMY_QT_TR_NOOP("propertyName", "scale") }, { Pid::LOCK_ASPECT_RATIO, false, "lockAspectRatio", P_TYPE::BOOL, PropertyGroup::APPEARANCE, DUMMY_QT_TR_NOOP("propertyName", "aspect ratio locked") }, diff --git a/src/engraving/dom/property.h b/src/engraving/dom/property.h index 4a33f3bba0350..2d238d3303231 100644 --- a/src/engraving/dom/property.h +++ b/src/engraving/dom/property.h @@ -155,7 +155,6 @@ enum class Pid { FRET_FRAME_CHORDS_PER_ROW, FRET_FRAME_H_ALIGN, FRET_FRAME_DIAGRAMS_ORDER, - FRET_FRAME_INVISIBLE_DIAGRAMS, SCALE, LOCK_ASPECT_RATIO, diff --git a/src/engraving/rendering/score/tlayout.cpp b/src/engraving/rendering/score/tlayout.cpp index d7599e4c7a7f5..9a159e3b75078 100644 --- a/src/engraving/rendering/score/tlayout.cpp +++ b/src/engraving/rendering/score/tlayout.cpp @@ -1497,17 +1497,14 @@ void TLayout::layoutFBox(const FBox* item, FBox::LayoutData* ldata, const Layout ldata->setPos(PointF()); - const ElementList& elements = item->orderedElements(true /*includeInvisible*/); - const StringList& invisibleDiagrams = item->invisibleDiagrams(); - std::vector fretDiagrams; - for (EngravingItem* element : elements) { + for (EngravingItem* element : item->el()) { if (!element || !element->isFretDiagram() || !element->visible()) { continue; } FretDiagram* diagram = toFretDiagram(element); - if (muse::contains(invisibleDiagrams, diagram->harmony()->harmonyName().toLower())) { + if (!diagram->visible()) { //! NOTE: We need to layout the diagrams to get the harmony names to show in the UI layoutItem(diagram, const_cast(ctx)); diff --git a/src/engraving/rw/read460/tread.cpp b/src/engraving/rw/read460/tread.cpp index 0a0ae71b391c4..8f7814988691f 100644 --- a/src/engraving/rw/read460/tread.cpp +++ b/src/engraving/rw/read460/tread.cpp @@ -2113,8 +2113,6 @@ void TRead::read(FBox* b, XmlReader& xml, ReadContext& ctx) } else if (readProperty(b, tag, xml, ctx, Pid::FRET_FRAME_ROW_GAP)) { } else if (readProperty(b, tag, xml, ctx, Pid::FRET_FRAME_CHORDS_PER_ROW)) { } else if (readProperty(b, tag, xml, ctx, Pid::FRET_FRAME_H_ALIGN)) { - } else if (readProperty(b, tag, xml, ctx, Pid::FRET_FRAME_DIAGRAMS_ORDER)) { - } else if (readProperty(b, tag, xml, ctx, Pid::FRET_FRAME_INVISIBLE_DIAGRAMS)) { } else if (TRead::readProperties(static_cast(b), xml, ctx)) { } else { xml.unknown(); diff --git a/src/engraving/rw/write/twrite.cpp b/src/engraving/rw/write/twrite.cpp index 299af42c6b25c..71373eb2291c8 100644 --- a/src/engraving/rw/write/twrite.cpp +++ b/src/engraving/rw/write/twrite.cpp @@ -822,8 +822,6 @@ void TWrite::write(const FBox* item, XmlWriter& xml, WriteContext& ctx) writeProperty(item, xml, Pid::FRET_FRAME_ROW_GAP); writeProperty(item, xml, Pid::FRET_FRAME_CHORDS_PER_ROW); writeProperty(item, xml, Pid::FRET_FRAME_H_ALIGN); - writeProperty(item, xml, Pid::FRET_FRAME_DIAGRAMS_ORDER); - writeProperty(item, xml, Pid::FRET_FRAME_INVISIBLE_DIAGRAMS); writeProperties(static_cast(item), xml, ctx); diff --git a/src/engraving/tests/fretbox_tests.cpp b/src/engraving/tests/fretbox_tests.cpp index 13a097fe28b1e..245f7efa1763d 100644 --- a/src/engraving/tests/fretbox_tests.cpp +++ b/src/engraving/tests/fretbox_tests.cpp @@ -161,7 +161,12 @@ class Engraving_FretBoxTests : public ::testing::Test FBox* fretBox = toFBox(score->measure(0)); ASSERT_TRUE(fretBox); - const ElementList& elements = fretBox->orderedElements(false /*includeInvisible*/); + ElementList elements; + for (EngravingItem* item : fretBox->el()) { + if (item->visible()) { + elements.push_back(item); + } + } EXPECT_EQ(elements.size(), chords.size()); for (size_t i = 0; i < chords.size(); ++i) { diff --git a/src/inspector/models/notation/frames/fretframe/fretframechordlistmodel.cpp b/src/inspector/models/notation/frames/fretframe/fretframechordlistmodel.cpp index 2ea2574cd8b51..e7a49f71e7fc5 100644 --- a/src/inspector/models/notation/frames/fretframe/fretframechordlistmodel.cpp +++ b/src/inspector/models/notation/frames/fretframe/fretframechordlistmodel.cpp @@ -57,15 +57,13 @@ void FretFrameChordListModel::load() return name; }; - const StringList& invisibleDiagrams = m_fretBox->invisibleDiagrams(); - - for (EngravingItem* element : m_fretBox->orderedElements(true /*includeInvisible*/)) { + for (EngravingItem* element : m_fretBox->el()) { FretDiagram* diagram = toFretDiagram(element); auto chordItem = new FretFrameChordItem(this); chordItem->setTitle(harmonyName(diagram->harmony())); chordItem->setPlainText(diagram->harmonyText()); - chordItem->setIsVisible(!muse::contains(invisibleDiagrams, diagram->harmony()->harmonyName().toLower())); + chordItem->setIsVisible(diagram->visible()); items << chordItem; } @@ -107,7 +105,7 @@ void FretFrameChordListModel::setChordVisible(int index, bool visible) return; } - ElementList diagrams = m_fretBox->orderedElements(true /*includeInvisible*/); + ElementList diagrams = m_fretBox->el(); if (index < 0 || index >= static_cast(diagrams.size())) { return; } @@ -124,16 +122,8 @@ void FretFrameChordListModel::setChordVisible(int index, bool visible) notation->undoStack()->prepareChanges(actionName); FretDiagram* diagram = toFretDiagram(diagrams[index]); - String harmonyName = diagram->harmony()->harmonyName().toLower(); - - StringList invisibleDiagrams = m_fretBox->invisibleDiagrams(); - if (visible) { - invisibleDiagrams.erase(std::remove(invisibleDiagrams.begin(), invisibleDiagrams.end(), harmonyName)); - } else { - invisibleDiagrams.push_back(harmonyName); - } - m_fretBox->undoSetInvisibleDiagrams(invisibleDiagrams); + diagram->undoChangeProperty(Pid::VISIBLE, visible); FretFrameChordItem* item = modelIndexToItem(this->index(index)); item->setIsVisible(visible); From 90b6760d40a103c3b004bee4dfd581c89a58fec0 Mon Sep 17 00:00:00 2001 From: Michele Spagnolo Date: Tue, 9 Sep 2025 13:26:47 +0200 Subject: [PATCH 10/13] Merge pull request #29705 from mike-spa/makeFDLIndependentInParts Make Fret Diagram legend independent in parts --- src/engraving/dom/box.cpp | 10 +++++++++- src/engraving/dom/measure.cpp | 6 +++++- src/engraving/dom/property.cpp | 2 +- src/inspector/models/parts/partssettingsmodel.cpp | 14 +++++++++++++- src/inspector/models/parts/partssettingsmodel.h | 4 ++++ .../MuseScore/Inspector/parts/PartsSettings.qml | 6 +++--- src/notation/internal/notationinteraction.cpp | 1 + 7 files changed, 36 insertions(+), 7 deletions(-) diff --git a/src/engraving/dom/box.cpp b/src/engraving/dom/box.cpp index 3431ba4daa074..5a636f6be4361 100644 --- a/src/engraving/dom/box.cpp +++ b/src/engraving/dom/box.cpp @@ -706,6 +706,9 @@ FBox::FBox(System* parent) resetProperty(Pid::BOTTOM_MARGIN); resetProperty(Pid::TOP_GAP); resetProperty(Pid::BOTTOM_GAP); + resetProperty(Pid::EXCLUDE_FROM_OTHER_PARTS); + resetProperty(Pid::APPEARANCE_LINKED_TO_MASTER); + resetProperty(Pid::POSITION_LINKED_TO_MASTER); } void FBox::init() @@ -722,7 +725,7 @@ void FBox::init() StringList diagramsNamesInScore; std::vector harmonyOrDiagramsInScore; - for (mu::engraving::Segment* segment = masterScore()->firstSegment(mu::engraving::SegmentType::ChordRest); segment; + for (mu::engraving::Segment* segment = score()->firstSegment(mu::engraving::SegmentType::ChordRest); segment; segment = segment->next1(mu::engraving::SegmentType::ChordRest)) { for (EngravingItem* item : segment->annotations()) { if (!item || !item->part()) { @@ -892,6 +895,11 @@ PropertyValue FBox::propertyDefault(Pid propertyId) const return static_cast(AlignH::HCENTER); case Pid::FRET_FRAME_DIAGRAMS_ORDER: return m_diagramsOrderInScore.join(FRET_BOX_DIAGRAMS_SEPARATOR); + case Pid::EXCLUDE_FROM_OTHER_PARTS: + return true; + case Pid::APPEARANCE_LINKED_TO_MASTER: + case Pid::POSITION_LINKED_TO_MASTER: + return false; default: return VBox::propertyDefault(propertyId); } diff --git a/src/engraving/dom/measure.cpp b/src/engraving/dom/measure.cpp index 8c4f9a4755958..e5b1935feefa6 100644 --- a/src/engraving/dom/measure.cpp +++ b/src/engraving/dom/measure.cpp @@ -1766,8 +1766,12 @@ EngravingItem* Measure::drop(EditData& data) score()->insertBox(ElementType::TBOX, this); break; case ActionIconType::FFRAME: - score()->insertBox(ElementType::FBOX, this); + { + Score::InsertMeasureOptions options; + options.cloneBoxToAllParts = false; + score()->insertBox(ElementType::FBOX, this, options); break; + } case ActionIconType::MEASURE: score()->insertMeasure(ElementType::MEASURE, this); break; diff --git a/src/engraving/dom/property.cpp b/src/engraving/dom/property.cpp index 462ca1360d40c..db00184e1fb20 100644 --- a/src/engraving/dom/property.cpp +++ b/src/engraving/dom/property.cpp @@ -147,7 +147,7 @@ static constexpr PropertyMetaData propertyList[] = { { Pid::FRET_FRAME_ROW_GAP, false, "fretFrameRowGap", P_TYPE::SPATIUM, PropertyGroup::APPEARANCE, DUMMY_QT_TR_NOOP("propertyName", "row gap") }, { Pid::FRET_FRAME_CHORDS_PER_ROW, false, "fretFrameChordsPerRow", P_TYPE::INT, PropertyGroup::APPEARANCE, DUMMY_QT_TR_NOOP("propertyName", "chords per row") }, { Pid::FRET_FRAME_H_ALIGN, false, "fretFrameHorizontalAlign", P_TYPE::INT, PropertyGroup::APPEARANCE, DUMMY_QT_TR_NOOP("propertyName", "horizontal alignment") }, - { Pid::FRET_FRAME_DIAGRAMS_ORDER, false, "fretFrameDiagramsOrder", P_TYPE::STRING, PropertyGroup::APPEARANCE, DUMMY_QT_TR_NOOP("propertyName", "diagrams order") }, + { Pid::FRET_FRAME_DIAGRAMS_ORDER, false, "fretFrameDiagramsOrder", P_TYPE::STRING, PropertyGroup::NONE, DUMMY_QT_TR_NOOP("propertyName", "diagrams order") }, { Pid::SCALE, false, "scale", P_TYPE::SCALE, PropertyGroup::APPEARANCE, DUMMY_QT_TR_NOOP("propertyName", "scale") }, { Pid::LOCK_ASPECT_RATIO, false, "lockAspectRatio", P_TYPE::BOOL, PropertyGroup::APPEARANCE, DUMMY_QT_TR_NOOP("propertyName", "aspect ratio locked") }, diff --git a/src/inspector/models/parts/partssettingsmodel.cpp b/src/inspector/models/parts/partssettingsmodel.cpp index 240bb5159386f..5f7a7d3c8f641 100644 --- a/src/inspector/models/parts/partssettingsmodel.cpp +++ b/src/inspector/models/parts/partssettingsmodel.cpp @@ -65,7 +65,7 @@ void PartsSettingsModel::requestElements() m_elementsForTextLinkingOption.clear(); for (EngravingItem* item : m_elementList) { - if (!item->score()->isMaster() && !item->isLayoutBreak()) { + if (!item->score()->isMaster() && !item->isLayoutBreak() && !item->isFBox()) { m_elementsForPartLinkingOption.push_back(item); } if (item->canBeExcludedFromOtherParts()) { @@ -101,6 +101,13 @@ void PartsSettingsModel::onNotationChanged(const PropertyIdSet&, const StyleIdSe loadProperties(); } +void PartsSettingsModel::onCurrentNotationChanged() +{ + emit isMasterScoreChanged(isMasterNotation()); + + AbstractInspectorModel::onCurrentNotationChanged(); +} + PropertyItem* PartsSettingsModel::positionLinkedToMaster() const { return m_positionLinkedToMaster; @@ -136,6 +143,11 @@ bool PartsSettingsModel::showTextLinkingOption() const return m_showTextLinkingOption; } +bool PartsSettingsModel::isMasterScore() const +{ + return isMasterNotation(); +} + void PartsSettingsModel::updateShowPartLinkingOption() { bool showPartLinking = !m_elementsForPartLinkingOption.empty(); diff --git a/src/inspector/models/parts/partssettingsmodel.h b/src/inspector/models/parts/partssettingsmodel.h index 4026c4dee7592..c853ac777675c 100644 --- a/src/inspector/models/parts/partssettingsmodel.h +++ b/src/inspector/models/parts/partssettingsmodel.h @@ -36,6 +36,7 @@ class PartsSettingsModel : public AbstractInspectorModel Q_PROPERTY(bool showPartLinkingOption READ showPartLinkingOption NOTIFY showPartLinkingOptionChanged) Q_PROPERTY(bool showExcludeOption READ showExcludeOption NOTIFY showExcludeOptionChanged) Q_PROPERTY(bool showTextLinkingOption READ showTextLinkingOption NOTIFY showTextLinkingOptionChanged) + Q_PROPERTY(bool isMasterScore READ isMasterScore NOTIFY isMasterScoreChanged) public: explicit PartsSettingsModel(QObject* parent, IElementRepositoryService* repository); @@ -48,11 +49,13 @@ class PartsSettingsModel : public AbstractInspectorModel bool showPartLinkingOption() const; bool showExcludeOption() const; bool showTextLinkingOption() const; + bool isMasterScore() const; signals: void showPartLinkingOptionChanged(bool showPartsOption); void showExcludeOptionChanged(bool excludeOption); void showTextLinkingOptionChanged(bool showTextLink); + void isMasterScoreChanged(bool isMasterScore); private: void createProperties() override; @@ -60,6 +63,7 @@ class PartsSettingsModel : public AbstractInspectorModel void loadProperties() override; void resetProperties() override; void onNotationChanged(const mu::engraving::PropertyIdSet&, const mu::engraving::StyleIdSet&) override; + void onCurrentNotationChanged() override; void updateShowPartLinkingOption(); void updateShowExcludeOption(); diff --git a/src/inspector/view/qml/MuseScore/Inspector/parts/PartsSettings.qml b/src/inspector/view/qml/MuseScore/Inspector/parts/PartsSettings.qml index 45bbe4a7f5a21..6bd8b0a27ca08 100644 --- a/src/inspector/view/qml/MuseScore/Inspector/parts/PartsSettings.qml +++ b/src/inspector/view/qml/MuseScore/Inspector/parts/PartsSettings.qml @@ -106,9 +106,9 @@ InspectorSectionView { navigation.panel: root.navigationPanel navigation.row: root.navigationRowStart - text: root.model && root.model.showPartLinkingOption - ? qsTrc("inspector", "Exclude from score") - : qsTrc("inspector", "Exclude from parts") + text: root.model && root.model.isMasterScore + ? qsTrc("inspector", "Exclude from parts") + : qsTrc("inspector", "Exclude from score") } } } diff --git a/src/notation/internal/notationinteraction.cpp b/src/notation/internal/notationinteraction.cpp index 770dfe3d0b916..403f65236dd37 100644 --- a/src/notation/internal/notationinteraction.cpp +++ b/src/notation/internal/notationinteraction.cpp @@ -5089,6 +5089,7 @@ void NotationInteraction::addBoxes(BoxType boxType, int count, int beforeBoxInde options.createEmptyMeasures = false; options.moveSignaturesClef = moveSignaturesClef; options.needDeselectAll = false; + options.cloneBoxToAllParts = boxType != BoxType::Fret; for (int i = 0; i < count; ++i) { score()->insertMeasure(elementType, beforeBox, options); From 5f1774476d6341d1c29733af73101f2e4ecef9c5 Mon Sep 17 00:00:00 2001 From: Michele Spagnolo Date: Fri, 5 Sep 2025 09:35:06 +0200 Subject: [PATCH 11/13] Merge pull request #29680 from miiizen/bassNoteSlashSpace Fix extra space in bass note slash --- src/engraving/dom/chordlist.cpp | 1 - src/engraving/rendering/score/harmonylayout.cpp | 2 +- src/engraving/rw/read460/tread.cpp | 3 --- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/engraving/dom/chordlist.cpp b/src/engraving/dom/chordlist.cpp index 9b6be0905f77c..cb40bb3129ded 100644 --- a/src/engraving/dom/chordlist.cpp +++ b/src/engraving/dom/chordlist.cpp @@ -1707,7 +1707,6 @@ const std::list& ParsedChord::renderList(const ChordList* cl, // Jazz superscript if (superScriptModifier) { // Set scale - LOGI() << "SCALE: " << cl->stackedModifierMag(); m_renderList.emplace_back(new RenderActionScale(cl->stackedModifierMag())); // Move to x-height m_renderList.emplace_back(new RenderActionPush()); diff --git a/src/engraving/rendering/score/harmonylayout.cpp b/src/engraving/rendering/score/harmonylayout.cpp index 3872820cfcafa..1c4add953bc13 100644 --- a/src/engraving/rendering/score/harmonylayout.cpp +++ b/src/engraving/rendering/score/harmonylayout.cpp @@ -500,7 +500,7 @@ void HarmonyLayout::renderSingleHarmony(Harmony* item, Harmony::LayoutData* ldat // render bass if (tpcIsValid(info->bassTpc())) { - std::list& bassNoteChordList + std::list bassNoteChordList = style.styleB(Sid::chordBassNoteStagger) ? chordList->renderListBassOffset : chordList->renderListBass; static const std::wregex PATTERN_69 = std::wregex(L"6[,/]?9"); diff --git a/src/engraving/rw/read460/tread.cpp b/src/engraving/rw/read460/tread.cpp index 8f7814988691f..430a3b1dde837 100644 --- a/src/engraving/rw/read460/tread.cpp +++ b/src/engraving/rw/read460/tread.cpp @@ -4344,9 +4344,6 @@ bool TRead::readProperties(TextBase* t, XmlReader& e, ReadContext& ctx) { const AsciiStringView tag(e.name()); for (Pid i : TextBasePropertyId) { - if (i == Pid::POSITION && tag == propertyName(i)) { - LOGI() << "read pos"; - } if (TRead::readProperty(t, tag, e, ctx, i)) { return true; } From 46e9a2b0eba04ff1994a97f3f2b81e928df6b026 Mon Sep 17 00:00:00 2001 From: James Mizen Date: Thu, 4 Sep 2025 16:28:10 +0100 Subject: [PATCH 12/13] Merge pull request #29687 from mike-spa/fixAnchorToEndOfPreviousInteractions Fix "anchor to end of previous" interactions --- src/engraving/dom/anchors.cpp | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/src/engraving/dom/anchors.cpp b/src/engraving/dom/anchors.cpp index 3886ec099ac24..8b72e731ee27f 100644 --- a/src/engraving/dom/anchors.cpp +++ b/src/engraving/dom/anchors.cpp @@ -158,18 +158,17 @@ void MoveElementAnchors::moveElementAnchors(EngravingItem* element, KeyboardKey return; } - bool leftRightKey = key == Key_Left || key == Key_Right; bool altMod = mod & AltModifier; - bool shiftMod = mod & ShiftModifier; - bool changeAnchorType = shiftMod && altMod && leftRightKey && canAnchorToEndOfPrevious(element); bool anchorToEndOfPrevious = element->getProperty(Pid::ANCHOR_TO_END_OF_PREVIOUS).toBool(); - if (changeAnchorType) { + bool changeAnchorType = altMod && canAnchorToEndOfPrevious(element); + bool resetAnchorType = !altMod && anchorToEndOfPrevious; + if (changeAnchorType || resetAnchorType) { element->undoChangeProperty(Pid::ANCHOR_TO_END_OF_PREVIOUS, !anchorToEndOfPrevious, element->propertyFlags(Pid::ANCHOR_TO_END_OF_PREVIOUS)); - bool doesntNeedMoveSeg = ((key == Key_Left && anchorToEndOfPrevious) || (key == Key_Right && !anchorToEndOfPrevious)); - if (doesntNeedMoveSeg) { + bool needMoveSeg = (key == Key_Left && anchorToEndOfPrevious) || (key == Key_Right && !anchorToEndOfPrevious); + if (!needMoveSeg) { checkMeasureBoundariesAndMoveIfNeed(element); return; } @@ -199,7 +198,7 @@ void MoveElementAnchors::checkMeasureBoundariesAndMoveIfNeed(EngravingItem* elem Measure* curMeasure = curSeg->measure(); Measure* prevMeasure = curMeasure->prevMeasure(); bool anchorToEndOfPrevious = element->getProperty(Pid::ANCHOR_TO_END_OF_PREVIOUS).toBool(); - bool needMoveToNext = curTick == curMeasure->endTick() && anchorToEndOfPrevious; + bool needMoveToNext = curTick == curMeasure->endTick() && !anchorToEndOfPrevious; bool needMoveToPrevious = curSeg->rtick().isZero() && anchorToEndOfPrevious && prevMeasure; if (!needMoveToPrevious && !needMoveToNext) { @@ -251,14 +250,6 @@ void MoveElementAnchors::moveElementAnchorsOnDrag(EngravingItem* element, EditDa void MoveElementAnchors::moveSegment(EngravingItem* element, bool forward) { - if (canAnchorToEndOfPrevious(element)) { - bool cachedAnchorToEndOfPrevious = element->getProperty(Pid::ANCHOR_TO_END_OF_PREVIOUS).toBool(); - element->undoResetProperty(Pid::ANCHOR_TO_END_OF_PREVIOUS); - if (cachedAnchorToEndOfPrevious && forward) { - return; - } - } - Segment* curSeg = toSegment(element->parentItem()); Segment* newSeg = getNewSegment(element, curSeg, forward); From 5aff5acb19632106186bb793da0c39f04a93bce5 Mon Sep 17 00:00:00 2001 From: Casper Jeukendrup <48658420+cbjeukendrup@users.noreply.github.com> Date: Mon, 8 Sep 2025 12:34:59 +0200 Subject: [PATCH 13/13] Merge pull request #29747 from rettinghaus/warning Unify fallthroughs --- src/engraving/api/v1/cursor.cpp | 3 ++- src/engraving/dom/harmony.cpp | 1 + src/engraving/dom/page.cpp | 8 ++++---- src/engraving/dom/pitchspelling.cpp | 4 ++-- src/engraving/dom/realizedharmony.cpp | 8 ++++---- 5 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/engraving/api/v1/cursor.cpp b/src/engraving/api/v1/cursor.cpp index 501e7fead85aa..e7d0738572ce2 100644 --- a/src/engraving/api/v1/cursor.cpp +++ b/src/engraving/api/v1/cursor.cpp @@ -363,7 +363,8 @@ void Cursor::add(EngravingItem* wrapped) s->setParent(curElement); m_score->undoAddElement(s); } - } // FALLTHROUGH + [[fallthrough]]; + } case ElementType::FINGERING: case ElementType::BEND: case ElementType::NOTEHEAD: { diff --git a/src/engraving/dom/harmony.cpp b/src/engraving/dom/harmony.cpp index c9c050a160710..d1341862ef5d3 100644 --- a/src/engraving/dom/harmony.cpp +++ b/src/engraving/dom/harmony.cpp @@ -1527,6 +1527,7 @@ bool Harmony::setProperty(Pid pid, const PropertyValue& v) } score()->rebuildFretBox(); } + break; } default: return TextBase::setProperty(pid, v); diff --git a/src/engraving/dom/page.cpp b/src/engraving/dom/page.cpp index 00a1aefe4b857..72d5e2127be2c 100644 --- a/src/engraving/dom/page.cpp +++ b/src/engraving/dom/page.cpp @@ -394,12 +394,12 @@ TextBlock Page::replaceTextMacros(const TextBlock& tb) const if (!m_no) { break; } - // FALLTHROUGH + [[fallthrough]]; case 'N': // on page 1 only if there are multiple pages if ((score()->npages() + score()->pageNumberOffset()) <= 1) { break; } - // FALLTHROUGH + [[fallthrough]]; case 'P': // on all pages { int no = static_cast(m_no) + 1 + score()->pageNumberOffset(); @@ -426,7 +426,7 @@ TextBlock Page::replaceTextMacros(const TextBlock& tb) const if (!m_no) { break; } - // FALLTHROUGH + [[fallthrough]]; case 'I': newFragments.back().text += score()->metaTag(u"partName"); break; @@ -471,7 +471,7 @@ TextBlock Page::replaceTextMacros(const TextBlock& tb) const if (m_no) { break; } - // FALLTHROUGH + [[fallthrough]]; case 'c': { const String copyrightString = score()->metaTag(u"copyright"); diff --git a/src/engraving/dom/pitchspelling.cpp b/src/engraving/dom/pitchspelling.cpp index 17ef621d522fc..e1dfbac5cbe5a 100644 --- a/src/engraving/dom/pitchspelling.cpp +++ b/src/engraving/dom/pitchspelling.cpp @@ -747,11 +747,11 @@ void Score::spellNotelist(std::vector& notes) case 3: k = end - start - 3; changeAllTpcs(notes[end - 3], tab[(notes[end - 3]->pitch() % 12) * 2 + ((opt & (1 << k)) >> k)]); - // FALLTHROUGH + [[fallthrough]]; case 2: k = end - start - 2; changeAllTpcs(notes[end - 2], tab[(notes[end - 2]->pitch() % 12) * 2 + ((opt & (1 << k)) >> k)]); - // FALLTHROUGH + [[fallthrough]]; case 1: k = end - start - 1; changeAllTpcs(notes[end - 1], tab[(notes[end - 1]->pitch() % 12) * 2 + ((opt & (1 << k)) >> k)]); diff --git a/src/engraving/dom/realizedharmony.cpp b/src/engraving/dom/realizedharmony.cpp index bdf734b67ac07..3e5a66e9e1d29 100644 --- a/src/engraving/dom/realizedharmony.cpp +++ b/src/engraving/dom/realizedharmony.cpp @@ -124,7 +124,7 @@ const RealizedHarmony::PitchMap RealizedHarmony::generateNotes(int rootTpc, int if (!m_harmony->parsedForm()->understandable()) { break; } - // FALLTHROUGH + [[fallthrough]]; case Voicing::CLOSE: //Voices notes in close position in the first octave above middle C { notes.insert({ rootPitch + DEFAULT_OCTAVE * PITCH_DELTA_OCTAVE, rootTpc }); @@ -439,7 +439,7 @@ RealizedHarmony::PitchMap RealizedHarmony::getIntervals(int rootTpc, bool litera ret.insert({ 9 + RANK_MULT * RANK_ADD, tpcInterval(rootTpc, 13, 0) }); //maj13 omit |= 1 << 13; } - // FALLTHROUGH + [[fallthrough]]; case 11: if (!(omit & (1 << 11))) { if (quality == "minor") { @@ -449,13 +449,13 @@ RealizedHarmony::PitchMap RealizedHarmony::getIntervals(int rootTpc, bool litera } omit |= 1 << 11; } - // FALLTHROUGH + [[fallthrough]]; case 9: if (!(omit & (1 << 9))) { ret.insert({ 2 + RANK_MULT * RANK_9TH, tpcInterval(rootTpc, 9, 0) }); //maj9 omit |= 1 << 9; } - // FALLTHROUGH + [[fallthrough]]; case 7: if (!(omit & (1 << 7))) { if (quality == "major") {