From ea85076b16ace69b46b80edcf2185edc5e12f67c Mon Sep 17 00:00:00 2001 From: Calum Matheson Date: Fri, 31 Jan 2025 12:08:06 +0000 Subject: [PATCH] Don't allow multiple staff type changes on the same measure --- src/engraving/dom/measure.cpp | 21 +++++++++++++++++++ src/engraving/dom/measure.h | 1 + src/notation/internal/notationinteraction.cpp | 8 +++++-- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/engraving/dom/measure.cpp b/src/engraving/dom/measure.cpp index 6bcc9e7f9401b..097c78d54b757 100644 --- a/src/engraving/dom/measure.cpp +++ b/src/engraving/dom/measure.cpp @@ -1395,6 +1395,9 @@ bool Measure::acceptDrop(EditData& data) const viewer->setDropRectangle(canvasBoundingRect()); return true; case ActionIconType::STAFF_TYPE_CHANGE: + if (!canAddStaffTypeChange(staffIdx)) { + return false; + } viewer->setDropRectangle(staffRect); return true; case ActionIconType::SYSTEM_LOCK: @@ -1736,6 +1739,9 @@ EngravingItem* Measure::drop(EditData& data) score()->insertMeasure(ElementType::MEASURE, this); break; case ActionIconType::STAFF_TYPE_CHANGE: { + if (!canAddStaffTypeChange(staffIdx)) { + return nullptr; + } EngravingItem* stc = Factory::createStaffTypeChange(this); stc->setParent(this); stc->setTrack(staffIdx * VOICES); @@ -3475,6 +3481,21 @@ bool Measure::canAddStringTunings(staff_idx_t staffIdx) const return !alreadyHasStringTunings; } +bool Measure::canAddStaffTypeChange(staff_idx_t staffIdx) const +{ + for (const EngravingObject* child : scanChildren()) { + if (!child || !child->isStaffTypeChange()) { + continue; + } + const StaffTypeChange* stc = toStaffTypeChange(child); + if (stc->staffIdx() == staffIdx) { + // Staff already has a StaffTypeChange at this measure... + return false; + } + } + return true; +} + Fraction Measure::maxTicks() const { Segment* s = first(); diff --git a/src/engraving/dom/measure.h b/src/engraving/dom/measure.h index 03c4e08ef5e53..2d68475f7f363 100644 --- a/src/engraving/dom/measure.h +++ b/src/engraving/dom/measure.h @@ -355,6 +355,7 @@ class Measure final : public MeasureBase void respaceSegments(); bool canAddStringTunings(staff_idx_t staffIdx) const; + bool canAddStaffTypeChange(staff_idx_t staffIdx) const; private: diff --git a/src/notation/internal/notationinteraction.cpp b/src/notation/internal/notationinteraction.cpp index 19a2c5687fba1..29087259ff1bb 100644 --- a/src/notation/internal/notationinteraction.cpp +++ b/src/notation/internal/notationinteraction.cpp @@ -2516,9 +2516,13 @@ bool NotationInteraction::dragMeasureAnchorElement(const PointF& pos) RectF measureRect = targetMeasure->staffPageBoundingRect(staffIdx); measureRect.adjust(page->x(), page->y(), page->x(), page->y()); m_dropData.ed.pos = measureRect.center(); - setAnchorLines({ LineF(pos, measureRect.topLeft()) }); - return targetMeasure->acceptDrop(m_dropData.ed); + const bool dropAccepted = targetMeasure->acceptDrop(m_dropData.ed); + if (dropAccepted) { + setAnchorLines({ LineF(pos, measureRect.topLeft()) }); + } + + return dropAccepted; } dropElem->score()->addRefresh(dropElem->canvasBoundingRect()); setDropTarget(nullptr);