Skip to content

Commit 1afc290

Browse files
authored
Merge pull request #26136 from mike-spa/fixSystemLockOnRemoveMeasures
Fix system locks on remove measures
2 parents 30ec683 + a12cf40 commit 1afc290

File tree

9 files changed

+132
-2
lines changed

9 files changed

+132
-2
lines changed

src/engraving/dom/edit.cpp

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6625,6 +6625,104 @@ void Score::removeLayoutBreaksOnAddSystemLock(const SystemLock* lock)
66256625
}
66266626
}
66276627

6628+
void Score::removeSystemLocksOnRemoveMeasures(const MeasureBase* m1, const MeasureBase* m2)
6629+
{
6630+
std::vector<const SystemLock*> allSysLocks = systemLocks()->allLocks();
6631+
for (const SystemLock* lock : allSysLocks) {
6632+
MeasureBase* lockStart = lock->startMB();
6633+
MeasureBase* lockEnd = lock->endMB();
6634+
bool lockStartIsInRange = lockStart->isAfterOrEqual(m1) && lockStart->isBeforeOrEqual(m2);
6635+
bool lockEndIsInRange = lockEnd->isAfterOrEqual(m1) && lockEnd->isBeforeOrEqual(m2);
6636+
if (lockStartIsInRange || lockEndIsInRange) {
6637+
undoRemoveSystemLock(lock);
6638+
}
6639+
if (lockStartIsInRange && !lockEndIsInRange) {
6640+
MeasureBase* newLockStart = m2->nextMeasure();
6641+
if (newLockStart) {
6642+
undoAddSystemLock(new SystemLock(newLockStart, lockEnd));
6643+
}
6644+
} else if (!lockStartIsInRange && lockEndIsInRange) {
6645+
MeasureBase* newLockEnd = m1->prevMeasure();
6646+
if (newLockEnd) {
6647+
undoAddSystemLock(new SystemLock(lockStart, newLockEnd));
6648+
}
6649+
}
6650+
}
6651+
}
6652+
6653+
void Score::updateSystemLocksOnDisableMMRests()
6654+
{
6655+
// NOTE: this can be done before layout for the full score
6656+
// because we already know where the mmRests are.
6657+
6658+
assert(!style().styleB(Sid::createMultiMeasureRests));
6659+
6660+
std::vector<const SystemLock*> allLocks = m_systemLocks.allLocks();
6661+
for (const SystemLock* lock : allLocks) {
6662+
MeasureBase* startMB = lock->startMB();
6663+
MeasureBase* endMB = lock->endMB();
6664+
bool startIsMMRest = startMB->isMeasure() && toMeasure(startMB)->isMMRest();
6665+
bool endIsMMRest = endMB->isMeasure() && toMeasure(endMB)->isMMRest();
6666+
if (startIsMMRest || endIsMMRest) {
6667+
undoRemoveSystemLock(lock);
6668+
MeasureBase* newStartMeas = startMB;
6669+
MeasureBase* newEndMeas = endMB;
6670+
if (startIsMMRest) {
6671+
newStartMeas = toMeasure(startMB)->mmRestFirst();
6672+
}
6673+
if (endIsMMRest) {
6674+
newEndMeas = toMeasure(endMB)->mmRestLast();
6675+
}
6676+
undoAddSystemLock(new SystemLock(newStartMeas, newEndMeas));
6677+
}
6678+
}
6679+
}
6680+
6681+
void Score::updateSystemLocksOnCreateMMRests(Measure* first, Measure* last)
6682+
{
6683+
// NOTE: this must be done during layout as the mmRests get created.
6684+
6685+
for (const SystemLock* lock : systemLocks()->locksContainedInRange(first, last)) {
6686+
// These locks are inside the range of the mmRest so remove them
6687+
undoRemoveSystemLock(lock);
6688+
}
6689+
6690+
const SystemLock* lockOnFirst = systemLocks()->lockContaining(first);
6691+
const SystemLock* lockOnLast = systemLocks()->lockContaining(last);
6692+
6693+
if (lockOnFirst) {
6694+
MeasureBase* startMB = lockOnFirst->startMB();
6695+
MeasureBase* endMB = lockOnFirst->endMB();
6696+
6697+
if (startMB->isBefore(first)) {
6698+
if (endMB->isBeforeOrEqual(last)) {
6699+
endMB = first->mmRest();
6700+
} else {
6701+
return;
6702+
}
6703+
} else {
6704+
startMB = first->mmRest();
6705+
}
6706+
6707+
if (startMB != lockOnFirst->startMB() || endMB != lockOnFirst->endMB()) {
6708+
undoRemoveSystemLock(lockOnFirst);
6709+
undoAddSystemLock(new SystemLock(startMB, endMB));
6710+
}
6711+
}
6712+
6713+
if (!lockOnLast || lockOnLast == lockOnFirst) {
6714+
return;
6715+
}
6716+
6717+
MeasureBase* startMB = lockOnLast->startMB();
6718+
MeasureBase* endMB = lockOnLast->endMB();
6719+
assert(startMB->isAfter(first) && endMB->isAfter(last));
6720+
6721+
undoRemoveSystemLock(lockOnLast);
6722+
startMB = last->nextMM();
6723+
undoAddSystemLock(new SystemLock(startMB, endMB));
6724+
}
6725+
66286726
//---------------------------------------------------------
66296727
// undoAddCR
66306728
//---------------------------------------------------------
@@ -7118,6 +7216,8 @@ void Score::undoRemoveMeasures(Measure* m1, Measure* m2, bool preserveTies, bool
71187216
}
71197217
}
71207218

7219+
removeSystemLocksOnRemoveMeasures(m1, m2);
7220+
71217221
undo(new RemoveMeasures(m1, m2, moveStaffTypeChanges));
71227222
}
71237223

src/engraving/dom/measurebase.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -706,11 +706,22 @@ bool MeasureBase::isBefore(const EngravingItem* other) const
706706

707707
bool MeasureBase::isBefore(const MeasureBase* other) const
708708
{
709+
if (this == other) {
710+
return false;
711+
}
712+
709713
Fraction otherTick = other->tick();
710714
if (otherTick != m_tick) {
711715
return m_tick < otherTick;
712716
}
713717

718+
if (this->isMeasure() && other->isMeasure()) {
719+
// (this == other) has already been excluded, so this is only
720+
// possible if one is the overlying mmRest starting on the other.
721+
// Let's set by convention that the mmRest isBefore the underlying measure.
722+
return toMeasure(this)->isMMRest();
723+
}
724+
714725
bool otherIsMMRest = other->isMeasure() && toMeasure(other)->isMMRest();
715726
for (const MeasureBase* mb = otherIsMMRest ? nextMM() : next(); mb && mb->tick() == m_tick;
716727
mb = otherIsMMRest ? mb->nextMM() : mb->next()) {

src/engraving/dom/score.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1021,6 +1021,9 @@ class Score : public EngravingObject, public muse::Injectable
10211021
void makeIntoSystem(MeasureBase* first, MeasureBase* last);
10221022
void removeSystemLocksOnAddLayoutBreak(LayoutBreakType breakType, const MeasureBase* measure);
10231023
void removeLayoutBreaksOnAddSystemLock(const SystemLock* lock);
1024+
void removeSystemLocksOnRemoveMeasures(const MeasureBase* m1, const MeasureBase* m2);
1025+
void updateSystemLocksOnDisableMMRests();
1026+
void updateSystemLocksOnCreateMMRests(Measure* first, Measure* last);
10241027

10251028
friend class Chord;
10261029

src/engraving/dom/systemlock.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ const SystemLock* SystemLocks::lockContaining(const MeasureBase* mb) const
7777
return lock->contains(mb) ? lock : nullptr;
7878
}
7979

80-
std::vector<const SystemLock*> SystemLocks::locksContainedInRange(const MeasureBase* start, const MeasureBase* end)
80+
std::vector<const SystemLock*> SystemLocks::locksContainedInRange(const MeasureBase* start, const MeasureBase* end) const
8181
{
8282
std::vector<const SystemLock*> result;
8383

src/engraving/dom/systemlock.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class SystemLocks
5858

5959
const SystemLock* lockStartingAt(const MeasureBase* mb) const;
6060
const SystemLock* lockContaining(const MeasureBase* mb) const;
61-
std::vector<const SystemLock*> locksContainedInRange(const MeasureBase* start, const MeasureBase* end);
61+
std::vector<const SystemLock*> locksContainedInRange(const MeasureBase* start, const MeasureBase* end) const;
6262

6363
std::vector<const SystemLock*> allLocks() const;
6464

src/engraving/dom/undo.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2039,6 +2039,11 @@ static void changeStyleValue(Score* score, Sid idx, const PropertyValue& oldValu
20392039
case Sid::defaultsVersion:
20402040
score->style().setDefaultStyleVersion(newValue.toInt());
20412041
break;
2042+
case Sid::createMultiMeasureRests:
2043+
if (oldValue.toBool() == true && newValue.toBool() == false) {
2044+
score->updateSystemLocksOnDisableMMRests();
2045+
}
2046+
break;
20422047
default:
20432048
break;
20442049
}

src/engraving/rendering/score/layoutcontext.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,14 @@ void DomAccessor::removeElement(EngravingItem* item)
392392
score()->removeElement(item);
393393
}
394394

395+
void DomAccessor::updateSystemLocksOnCreateMMRest(Measure* first, Measure* last)
396+
{
397+
IF_ASSERT_FAILED(score()) {
398+
return;
399+
}
400+
score()->updateSystemLocksOnCreateMMRests(first, last);
401+
}
402+
395403
void DomAccessor::addUnmanagedSpanner(Spanner* s)
396404
{
397405
IF_ASSERT_FAILED(score()) {

src/engraving/rendering/score/layoutcontext.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ class DomAccessor
198198
void undo(UndoCommand* cmd, EditData* ed = nullptr) const;
199199
void addElement(EngravingItem* item);
200200
void removeElement(EngravingItem* item);
201+
void updateSystemLocksOnCreateMMRest(Measure* first, Measure* last);
201202

202203
void addUnmanagedSpanner(Spanner* s);
203204
const std::set<Spanner*>& unmanagedSpanners() const;

src/engraving/rendering/score/measurelayout.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,8 @@ void MeasureLayout::createMMRest(LayoutContext& ctx, Measure* firstMeasure, Meas
227227
mmrMeasure->setMMRestCount(numMeasuresInMMRest);
228228
mmrMeasure->setNo(firstMeasure->no());
229229

230+
ctx.mutDom().updateSystemLocksOnCreateMMRest(firstMeasure, lastMeasure);
231+
230232
//
231233
// set mmrMeasure with same barline as last underlying measure
232234
//

0 commit comments

Comments
 (0)