Skip to content

Commit

Permalink
Don't mess up brackets in Score::undoAddBracket
Browse files Browse the repository at this point in the history
We seem to assume that for each staff, for each of its brackets, the column of the bracket is equal to the index at which the bracket is stored in `_brackets`. But this is completely messed up in `Score::undoAddBracket`. We update the column of the brackets, but don't move them in the list, which is wrong. This caused a crash somewhere later.

The solution is to also move them in the list, but we need to do that carefully: brackets might be "cleaned up", which means that brackets with `BracketType::NO_BRACKET` at the end of the list are deleted (as in, immediately destroyed). This means that we must be careful about brackets with type `NO_BRACKET`, and the length of the list may decrease.
  • Loading branch information
cbjeukendrup committed May 8, 2023
1 parent 5fc30ff commit ce01ab2
Showing 1 changed file with 17 additions and 3 deletions.
20 changes: 17 additions & 3 deletions src/engraving/libmscore/edit.cpp
Expand Up @@ -6299,15 +6299,29 @@ void Score::undoAddBracket(Staff* staff, size_t level, BracketType type, size_t
{
staff_idx_t startStaffIdx = staff->idx();
staff_idx_t totStaves = nstaves();

// Make sure this brackets won't overlap with others sharing same column.
// If overlaps are found, move the other brackets outwards (i.e. increase column).
for (staff_idx_t staffIdx = startStaffIdx; staffIdx < startStaffIdx + span && staffIdx < totStaves; ++staffIdx) {
for (BracketItem* bracketItem : _staves.at(staffIdx)->brackets()) {
if (bracketItem->column() >= level) {
bracketItem->setColumn(bracketItem->column() + 1);
const std::vector<BracketItem*>& brackets = _staves.at(staffIdx)->brackets();

for (int i = static_cast<int>(brackets.size()) - 1; i >= static_cast<int>(level); --i) {
if (i >= static_cast<int>(brackets.size())) {
// This might theoretically happen when a lot of brackets get cleaned up
// after changing the column of the first bracket we see
continue;
}

if (brackets[i]->bracketType() == BracketType::NO_BRACKET) {
// Better not get brackets with type NO_BRACKET in the UndoStack,
// as they might be cleaned up (Staff::cleanupBrackets())
continue;
}

brackets[i]->undoChangeProperty(Pid::BRACKET_COLUMN, brackets[i]->column() + 1);
}
}

undo(new AddBracket(staff, level, type, span));
}

Expand Down

0 comments on commit ce01ab2

Please sign in to comment.