Skip to content

Commit

Permalink
Merge pull request #9369 from RomanPudashkin/crash_during_removing_la…
Browse files Browse the repository at this point in the history
…st_instrument

[MU4] Fixed various crashes during removing staves
  • Loading branch information
Eism authored Oct 8, 2021
2 parents ece925a + 19589da commit 76a446e
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 22 deletions.
42 changes: 27 additions & 15 deletions src/engraving/libmscore/edit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4965,33 +4965,45 @@ void Score::undoInsertPart(Part* part, int idx)

void Score::undoRemoveStaff(Staff* staff)
{
const int idx = staff->idx();
Q_ASSERT(idx >= 0);
const int staffIndex = staff->idx();
Q_ASSERT(staffIndex >= 0);

std::vector<Spanner*> toRemove;
for (auto i = _spanner.cbegin(); i != _spanner.cend(); ++i) {
Spanner* s = i->second;
if (s->staffIdx() == idx && (idx != 0 || !s->systemFlag())) {
toRemove.push_back(s);
auto removingAllowed = [staffIndex, this](const Spanner* spanner) {
if (spanner->staffIdx() != staffIndex) {
return false;
}

return staffIndex != 0 || _staves.size() == 1 || !spanner->systemFlag();
};

std::vector<Spanner*> spannersToRemove;

for (auto it = _spanner.cbegin(); it != _spanner.cend(); ++it) {
Spanner* spanner = it->second;

if (removingAllowed(spanner)) {
spannersToRemove.push_back(spanner);
}
}
for (Spanner* s : _unmanagedSpanner) {
if (s->staffIdx() == idx && (idx != 0 || !s->systemFlag())) {
toRemove.push_back(s);

for (Spanner* spanner : _unmanagedSpanner) {
if (removingAllowed(spanner)) {
spannersToRemove.push_back(spanner);
}
}
for (Spanner* s : toRemove) {
s->undoUnlink();
undo(new RemoveElement(s));

for (Spanner* spanner : spannersToRemove) {
spanner->undoUnlink();
undo(new RemoveElement(spanner));
}

//
// adjust measures
//
for (Measure* m = staff->score()->firstMeasure(); m; m = m->nextMeasure()) {
m->cmdRemoveStaves(idx, idx + 1);
m->cmdRemoveStaves(staffIndex, staffIndex + 1);
if (m->hasMMRest()) {
m->mmRest()->cmdRemoveStaves(idx, idx + 1);
m->mmRest()->cmdRemoveStaves(staffIndex, staffIndex + 1);
}
}

Expand Down
5 changes: 4 additions & 1 deletion src/engraving/libmscore/engravingitem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -670,8 +670,11 @@ PointF EngravingItem::canvasPos() const
qFatal("this %s parent %s\n", name(), parent()->name());
}
if (measure) {
p.ry() += measure->staffLines(vStaffIdx())->y();
const StaffLines* lines = measure->staffLines(vStaffIdx());
p.ry() += lines ? lines->y() : 0;

system = measure->system();

if (system) {
Page* page = system->page();
if (page) {
Expand Down
19 changes: 14 additions & 5 deletions src/engraving/libmscore/measure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1249,6 +1249,14 @@ void Measure::cmdRemoveStaves(int sStaff, int eStaff)
{
int sTrack = sStaff * VOICES;
int eTrack = eStaff * VOICES;

auto removingAllowed = [this, sStaff, eStaff](const EngravingItem* item) {
int staffIndex = item->staffIdx();
int staffCount = score()->nstaves();

return (staffIndex >= sStaff) && (staffIndex < eStaff) && (!item->systemFlag() || staffCount == 1);
};

for (Segment* s = first(); s; s = s->next()) {
for (int track = eTrack - 1; track >= sTrack; --track) {
EngravingItem* el = s->element(track);
Expand All @@ -1257,20 +1265,21 @@ void Measure::cmdRemoveStaves(int sStaff, int eStaff)
score()->undo(new RemoveElement(el));
}
}
foreach (EngravingItem* e, s->annotations()) {
int staffIdx = e->staffIdx();
if ((staffIdx >= sStaff) && (staffIdx < eStaff) && !e->systemFlag()) {

for (EngravingItem* e : s->annotations()) {
if (removingAllowed(e)) {
e->undoUnlink();
score()->undo(new RemoveElement(e));
}
}
}

for (EngravingItem* e : el()) {
if (e->track() == -1) {
continue;
}
int staffIdx = e->staffIdx();
if (staffIdx >= sStaff && (staffIdx < eStaff) && !e->systemFlag()) {

if (removingAllowed(e)) {
e->undoUnlink();
score()->undo(new RemoveElement(e));
}
Expand Down
3 changes: 2 additions & 1 deletion src/engraving/libmscore/system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1294,9 +1294,10 @@ void System::scanElements(void* data, void (* func)(void*, EngravingItem*), bool

qreal System::staffYpage(int staffIdx) const
{
IF_ASSERT_FAILED(!(_staves.size() <= staffIdx || staffIdx < 0)) {
if (staffIdx < 0 || staffIdx >= _staves.size()) {
return pagePos().y();
}

return _staves[staffIdx]->y() + y();
}

Expand Down

0 comments on commit 76a446e

Please sign in to comment.