Merge pull request #18038 from cbjeukendrup/crash_musicxml_export_after_toggle_mmrest
Fix crash when exporting to MusicXML after toggling MMRests
This commit is contained in:
commit
92c12fb2f5
|
@ -2737,7 +2737,7 @@ EngravingItem* Score::move(const String& cmd)
|
|||
}
|
||||
if (ftm) {
|
||||
if (score()->styleB(Sid::createMultiMeasureRests) && ftm->hasMMRest()) {
|
||||
ftm = ftm->mmRest1();
|
||||
ftm = ftm->coveringMMRestOrThis();
|
||||
}
|
||||
el = !cr ? ftm->first()->nextChordRest(0, false) : ftm->first()->nextChordRest(trackZeroVoice(cr->track()), false);
|
||||
}
|
||||
|
|
|
@ -1051,9 +1051,9 @@ PointF SLine::linePos(Grip grip, System** sys) const
|
|||
}
|
||||
}
|
||||
}
|
||||
if (score()->styleB(Sid::createMultiMeasureRests)) {
|
||||
m = m->mmRest1();
|
||||
}
|
||||
|
||||
m = m->coveringMMRestOrThis();
|
||||
|
||||
assert(m->system());
|
||||
*sys = m->system();
|
||||
}
|
||||
|
|
|
@ -2729,27 +2729,36 @@ Measure* Measure::mmRestLast() const
|
|||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// mmRest1
|
||||
// return the multi measure rest this measure is covered
|
||||
// by
|
||||
// coveringMMRestOrThis
|
||||
// if multi-measure rests are enabled,
|
||||
// and this measure is covered by an MMRest,
|
||||
// return that MMRest.
|
||||
// otherwise, return the measure itself.
|
||||
//---------------------------------------------------------
|
||||
|
||||
const Measure* Measure::mmRest1() const
|
||||
const Measure* Measure::coveringMMRestOrThis() const
|
||||
{
|
||||
if (!score()->styleB(Sid::createMultiMeasureRests)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
if (m_mmRest) {
|
||||
return m_mmRest;
|
||||
}
|
||||
|
||||
if (m_mmRestCount != -1) {
|
||||
// return const_cast<Measure*>(this);
|
||||
return this;
|
||||
}
|
||||
|
||||
const Measure* m = this;
|
||||
while (m && !m->m_mmRest) {
|
||||
m = m->prevMeasure();
|
||||
}
|
||||
|
||||
if (m) {
|
||||
return const_cast<Measure*>(m->m_mmRest);
|
||||
return m->m_mmRest;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -304,7 +304,7 @@ public:
|
|||
bool hasMMRest() const { return m_mmRest != 0; }
|
||||
bool isMMRest() const { return m_mmRestCount > 0; }
|
||||
Measure* mmRest() const { return m_mmRest; }
|
||||
const Measure* mmRest1() const;
|
||||
const Measure* coveringMMRestOrThis() const;
|
||||
void setMMRest(Measure* m) { m_mmRest = m; }
|
||||
int mmRestCount() const { return m_mmRestCount; } // number of measures m_mmRest spans
|
||||
void setMMRestCount(int n) { m_mmRestCount = n; }
|
||||
|
|
|
@ -566,7 +566,7 @@ MeasureBase* MeasureBase::prevMM() const
|
|||
if (_prev
|
||||
&& _prev->isMeasure()
|
||||
&& score()->styleB(Sid::createMultiMeasureRests)) {
|
||||
return const_cast<Measure*>(toMeasure(_prev)->mmRest1());
|
||||
return const_cast<Measure*>(toMeasure(_prev)->coveringMMRestOrThis());
|
||||
}
|
||||
return _prev;
|
||||
}
|
||||
|
|
|
@ -1948,13 +1948,7 @@ Measure* Score::lastMeasure() const
|
|||
Measure* Score::lastMeasureMM() const
|
||||
{
|
||||
Measure* m = lastMeasure();
|
||||
if (m && styleB(Sid::createMultiMeasureRests)) {
|
||||
Measure* m1 = const_cast<Measure*>(toMeasure(m->mmRest1()));
|
||||
if (m1) {
|
||||
return m1;
|
||||
}
|
||||
}
|
||||
return m;
|
||||
return m ? const_cast<Measure*>(m->coveringMMRestOrThis()) : nullptr;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
@ -4633,7 +4627,7 @@ ChordRest* Score::cmdNextPrevSystem(ChordRest* cr, bool next)
|
|||
{
|
||||
auto newCR = cr;
|
||||
auto currentMeasure = cr->measure();
|
||||
auto currentSystem = currentMeasure->system() ? currentMeasure->system() : currentMeasure->mmRest1()->system();
|
||||
auto currentSystem = currentMeasure->system() ? currentMeasure->system() : currentMeasure->coveringMMRestOrThis()->system();
|
||||
if (!currentSystem) {
|
||||
return cr;
|
||||
}
|
||||
|
@ -4644,7 +4638,9 @@ ChordRest* Score::cmdNextPrevSystem(ChordRest* cr, bool next)
|
|||
if (next) {
|
||||
if ((destinationMeasure = currentSystem->lastMeasure()->nextMeasure())) {
|
||||
// There is a next system present: get it and accommodate for MMRest
|
||||
currentSystem = destinationMeasure->system() ? destinationMeasure->system() : destinationMeasure->mmRest1()->system();
|
||||
currentSystem = destinationMeasure->system()
|
||||
? destinationMeasure->system()
|
||||
: destinationMeasure->coveringMMRestOrThis()->system();
|
||||
if ((destinationMeasure = currentSystem->firstMeasure())) {
|
||||
if ((newCR = destinationMeasure->first()->nextChordRest(trackZeroVoice(cr->track()), false))) {
|
||||
cr = newCR;
|
||||
|
@ -4678,7 +4674,9 @@ ChordRest* Score::cmdNextPrevSystem(ChordRest* cr, bool next)
|
|||
return cr;
|
||||
}
|
||||
}
|
||||
if (!(currentSystem = destinationMeasure->system() ? destinationMeasure->system() : destinationMeasure->mmRest1()->system())) {
|
||||
if (!(currentSystem = destinationMeasure->system()
|
||||
? destinationMeasure->system()
|
||||
: destinationMeasure->coveringMMRestOrThis()->system())) {
|
||||
return cr;
|
||||
}
|
||||
destinationMeasure = currentSystem->firstMeasure();
|
||||
|
@ -4814,7 +4812,7 @@ EngravingItem* Score::getScoreElementOfMeasureBase(MeasureBase* mb) const
|
|||
} else if ((currentMeasure = mb->findMeasure())) {
|
||||
// Accommodate for MMRest
|
||||
if (score()->styleB(Sid::createMultiMeasureRests) && currentMeasure->hasMMRest()) {
|
||||
currentMeasure = currentMeasure->mmRest1();
|
||||
currentMeasure = currentMeasure->coveringMMRestOrThis();
|
||||
}
|
||||
if ((cr = currentMeasure->first()->nextChordRest(0, false))) {
|
||||
el = cr;
|
||||
|
@ -4876,7 +4874,7 @@ ChordRest* Score::cmdTopStaff(ChordRest* cr)
|
|||
if (destinationMeasure) {
|
||||
// Accommodate for MMRest
|
||||
if (score()->styleB(Sid::createMultiMeasureRests) && destinationMeasure->hasMMRest()) {
|
||||
destinationMeasure = destinationMeasure->mmRest1();
|
||||
destinationMeasure = destinationMeasure->coveringMMRestOrThis();
|
||||
}
|
||||
// Get first ChordRest of top staff
|
||||
cr = destinationMeasure->first()->nextChordRest(0, false);
|
||||
|
|
|
@ -173,7 +173,7 @@ EngravingObject* Measure::scanParent() const
|
|||
if (isMMRest()) { // this is MMR
|
||||
return system();
|
||||
} else if (m_mmRestCount < 0) { // this is part of MMR
|
||||
return const_cast<Measure*>(mmRest1());
|
||||
return const_cast<Measure*>(coveringMMRestOrThis());
|
||||
}
|
||||
// for a normal measure
|
||||
return system();
|
||||
|
|
|
@ -559,7 +559,7 @@ void Selection::updateSelectedElements()
|
|||
return;
|
||||
}
|
||||
|
||||
if (s2 && s2 == s2->measure()->first() && !(s2->measure()->prevMeasure() && s2->measure()->prevMeasure()->mmRest1())) {
|
||||
if (s2 && s2 == s2->measure()->first() && !(s2->measure()->prevMeasure() && s2->measure()->prevMeasure()->coveringMMRestOrThis())) {
|
||||
// we want the last segment of the previous measure (unless it's part of a MMrest)
|
||||
s2 = s2->prev1();
|
||||
}
|
||||
|
|
|
@ -1939,7 +1939,7 @@ static void writeBarlineFermata(const BarLine* const barline, XmlWriter& xml, co
|
|||
|
||||
void ExportMusicXml::barlineRight(const Measure* const m, const track_idx_t strack, const track_idx_t etrack)
|
||||
{
|
||||
const Measure* mmR1 = m->mmRest1(); // the multi measure rest this measure is covered by
|
||||
const Measure* mmR1 = m->coveringMMRestOrThis(); // the multi measure rest this measure is covered by
|
||||
const Measure* mmRLst = mmR1->isMMRest() ? mmR1->mmRestLast() : 0; // last measure of replaced sequence of empty measures
|
||||
// note: use barlinetype as found in multi measure rest for last measure of replaced sequence
|
||||
BarLineType bst = m == mmRLst ? mmR1->endBarLineType() : m->endBarLineType();
|
||||
|
@ -5588,7 +5588,7 @@ static void measureRepeat(XmlWriter& xml, Attributes& attr, const Measure* const
|
|||
|
||||
static void measureStyle(XmlWriter& xml, Attributes& attr, const Measure* const m, const int partIndex)
|
||||
{
|
||||
const Measure* mmR1 = m->mmRest1();
|
||||
const Measure* mmR1 = m->coveringMMRestOrThis();
|
||||
if (m != mmR1 && m == mmR1->mmRestFirst()) {
|
||||
attr.doAttr(xml, true);
|
||||
xml.startElement("measure-style");
|
||||
|
@ -6376,7 +6376,7 @@ void ExportMusicXml::print(const Measure* const m, const int partNr, const int f
|
|||
// in the replacing measure
|
||||
// note: for a normal measure, mmRest1 is the measure itself,
|
||||
// for a multi-measure rest, it is the replacing measure
|
||||
const Measure* mmR1 = m->mmRest1();
|
||||
const Measure* mmR1 = m->coveringMMRestOrThis();
|
||||
const System* system = mmR1->system();
|
||||
|
||||
// Put the system print suggestions only for the first part in a score...
|
||||
|
@ -7008,7 +7008,7 @@ static System* findLastSystemWithMeasures(const Page* const page)
|
|||
|
||||
static bool isFirstMeasureInSystem(const Measure* const measure)
|
||||
{
|
||||
const auto system = measure->mmRest1()->system();
|
||||
const auto system = measure->coveringMMRestOrThis()->system();
|
||||
const auto firstMeasureInSystem = system->firstMeasure();
|
||||
const auto realFirstMeasureInSystem = firstMeasureInSystem->isMMRest() ? firstMeasureInSystem->mmRestFirst() : firstMeasureInSystem;
|
||||
return measure == realFirstMeasureInSystem;
|
||||
|
@ -7020,7 +7020,7 @@ static bool isFirstMeasureInSystem(const Measure* const measure)
|
|||
|
||||
static bool isFirstMeasureInLastSystem(const Measure* const measure)
|
||||
{
|
||||
const auto system = measure->mmRest1()->system();
|
||||
const auto system = measure->coveringMMRestOrThis()->system();
|
||||
const auto page = system->page();
|
||||
|
||||
/*
|
||||
|
@ -7057,7 +7057,7 @@ static bool systemHasMeasures(const System* const system)
|
|||
|
||||
static std::vector<TBox*> findTextFramesToWriteAsWordsAbove(const Measure* const measure)
|
||||
{
|
||||
const auto system = measure->mmRest1()->system();
|
||||
const auto system = measure->coveringMMRestOrThis()->system();
|
||||
const auto page = system->page();
|
||||
const size_t systemIndex = mu::indexOf(page->systems(), system);
|
||||
std::vector<TBox*> tboxes;
|
||||
|
@ -7081,7 +7081,7 @@ static std::vector<TBox*> findTextFramesToWriteAsWordsAbove(const Measure* const
|
|||
|
||||
static std::vector<TBox*> findTextFramesToWriteAsWordsBelow(const Measure* const measure)
|
||||
{
|
||||
const auto system = measure->mmRest1()->system();
|
||||
const auto system = measure->coveringMMRestOrThis()->system();
|
||||
const auto page = system->page();
|
||||
const size_t systemIndex = static_cast<int>(mu::indexOf(page->systems(), system));
|
||||
std::vector<TBox*> tboxes;
|
||||
|
@ -7147,15 +7147,16 @@ void ExportMusicXml::writeMeasureTracks(const Measure* const m,
|
|||
for (const auto tbox : tboxesAbove) {
|
||||
// note: use mmRest1() to get at a possible multi-measure rest,
|
||||
// as the covered measure would be positioned at 0,0.
|
||||
tboxTextAsWords(tbox->text(), 0, mu::PointF(tbox->text()->canvasPos() - m->mmRest1()->canvasPos()).toQPointF());
|
||||
tboxTextAsWords(tbox->text(), 0, mu::PointF(
|
||||
tbox->text()->canvasPos() - m->coveringMMRestOrThis()->canvasPos()).toQPointF());
|
||||
}
|
||||
_tboxesAboveWritten = true;
|
||||
}
|
||||
if (!_tboxesBelowWritten && isLastPart && isLastStaffOfPart) {
|
||||
for (const auto tbox : tboxesBelow) {
|
||||
const auto lastStaffNr = track2staff(track);
|
||||
const auto sys = m->mmRest1()->system();
|
||||
auto textPos = tbox->text()->canvasPos() - m->mmRest1()->canvasPos();
|
||||
const auto sys = m->coveringMMRestOrThis()->system();
|
||||
auto textPos = tbox->text()->canvasPos() - m->coveringMMRestOrThis()->canvasPos();
|
||||
if (lastStaffNr < sys->staves().size()) {
|
||||
// convert to position relative to last staff of system
|
||||
textPos.setY(textPos.y() - (sys->staffCanvasYpage(lastStaffNr) - sys->staffCanvasYpage(0)));
|
||||
|
|
|
@ -2637,7 +2637,7 @@ void NotationInteraction::selectEmptyTrailingMeasure()
|
|||
}
|
||||
if (ftm) {
|
||||
if (score()->styleB(mu::engraving::Sid::createMultiMeasureRests) && ftm->hasMMRest()) {
|
||||
ftm = ftm->mmRest1();
|
||||
ftm = ftm->coveringMMRestOrThis();
|
||||
}
|
||||
EngravingItem* el
|
||||
= !cr ? ftm->first()->nextChordRest(0, false) : ftm->first()->nextChordRest(mu::engraving::trackZeroVoice(cr->track()), false);
|
||||
|
|
|
@ -173,7 +173,7 @@ mu::engraving::Segment* NotationSelectionRange::rangeStartSegment() const
|
|||
}
|
||||
|
||||
if (!startSegment->measure()->system()) {
|
||||
const Measure* mmr = startSegment->measure()->mmRest1();
|
||||
const Measure* mmr = startSegment->measure()->coveringMMRestOrThis();
|
||||
if (!mmr || mmr->system()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -226,7 +226,7 @@ const
|
|||
mu::engraving::System* nextSegmentSystem = nextSegment->measure()->system();
|
||||
|
||||
if (!nextSegmentSystem) {
|
||||
const Measure* mmr = nextSegment->measure()->mmRest1();
|
||||
const Measure* mmr = nextSegment->measure()->coveringMMRestOrThis();
|
||||
if (mmr) {
|
||||
nextSegmentSystem = mmr->system();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue