From 0281cc77f99f17624c88a786678082faa0d36929 Mon Sep 17 00:00:00 2001 From: Roman Pudashkin Date: Mon, 4 Oct 2021 16:08:40 +0200 Subject: [PATCH 1/2] fixed crash during removing the last staff --- src/engraving/libmscore/engravingitem.cpp | 5 ++++- src/engraving/libmscore/system.cpp | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/engraving/libmscore/engravingitem.cpp b/src/engraving/libmscore/engravingitem.cpp index 7f1b082488c53..38e6fec0940d1 100644 --- a/src/engraving/libmscore/engravingitem.cpp +++ b/src/engraving/libmscore/engravingitem.cpp @@ -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) { diff --git a/src/engraving/libmscore/system.cpp b/src/engraving/libmscore/system.cpp index fced0d8eb63d7..448c5c5a658bc 100644 --- a/src/engraving/libmscore/system.cpp +++ b/src/engraving/libmscore/system.cpp @@ -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(); } From 19589da89712175b631b5e1e4b7bcc0b9e49b1aa Mon Sep 17 00:00:00 2001 From: Roman Pudashkin Date: Tue, 5 Oct 2021 11:56:31 +0200 Subject: [PATCH 2/2] fixed removing spanners (e.g. volta lines) and annotations after removing all staves from a score --- src/engraving/libmscore/edit.cpp | 42 ++++++++++++++++++----------- src/engraving/libmscore/measure.cpp | 19 +++++++++---- 2 files changed, 41 insertions(+), 20 deletions(-) diff --git a/src/engraving/libmscore/edit.cpp b/src/engraving/libmscore/edit.cpp index 01ab8ddacbe96..4234f56a22727 100644 --- a/src/engraving/libmscore/edit.cpp +++ b/src/engraving/libmscore/edit.cpp @@ -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 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 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); } } diff --git a/src/engraving/libmscore/measure.cpp b/src/engraving/libmscore/measure.cpp index 0fb9989055c9a..ceed17b7a5a2a 100644 --- a/src/engraving/libmscore/measure.cpp +++ b/src/engraving/libmscore/measure.cpp @@ -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); @@ -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)); }