From 9079e316e580faeb9259c95b67bdc32008165da1 Mon Sep 17 00:00:00 2001 From: Werner Schweer Date: Mon, 10 Dec 2012 14:00:17 +0100 Subject: [PATCH] remove incomplete spanner when loading corrupted score --- libmscore/measure.cpp | 1 + libmscore/measure.h | 1 - libmscore/note.cpp | 2 +- libmscore/rendermidi.cpp | 5 +++ libmscore/scorefile.cpp | 86 +++++++++++++++++++++++++--------------- mscore/debugger.cpp | 4 +- 6 files changed, 65 insertions(+), 34 deletions(-) diff --git a/libmscore/measure.cpp b/libmscore/measure.cpp index 8e7a6d4e07127..b0a8be0b790c8 100644 --- a/libmscore/measure.cpp +++ b/libmscore/measure.cpp @@ -2058,6 +2058,7 @@ void Measure::read(const QDomElement& de, int staffIdx) || tag == "TextLine" || tag == "Volta") { Spanner* sp = static_cast(Element::name2Element(tag, score())); + score()->spanner.append(sp); sp->setTrack(staffIdx * VOICES); sp->read(e); segment = getSegment(Segment::SegChordRest, score()->curTick); diff --git a/libmscore/measure.h b/libmscore/measure.h index 8b6f6fb040138..1ec21a8fd20af 100644 --- a/libmscore/measure.h +++ b/libmscore/measure.h @@ -143,7 +143,6 @@ class Measure : public MeasureBase { virtual void read(const QDomElement&, int idx); void read(const QDomElement& d) { read(d, 0); } virtual void write(Xml&, int, bool writeSystemElements) const; -// virtual void write(Xml&) const; void writeBox(Xml&) const; void readBox(const QDomElement&); virtual bool isEditable() const { return false; } diff --git a/libmscore/note.cpp b/libmscore/note.cpp index e75f44c3eaa39..129e0150717f1 100644 --- a/libmscore/note.cpp +++ b/libmscore/note.cpp @@ -877,7 +877,7 @@ void Note::read(const QDomElement& de) _spannerBack.append(e); } else - qDebug("Measure::read(): cannot find spanner %d", id); + qDebug("Note::read(): cannot find spanner %d", id); } else if (tag == "TextLine") { Spanner* sp = static_cast(Element::name2Element(tag, score())); diff --git a/libmscore/rendermidi.cpp b/libmscore/rendermidi.cpp index 120fccb0584c5..505fba77698e9 100644 --- a/libmscore/rendermidi.cpp +++ b/libmscore/rendermidi.cpp @@ -309,6 +309,11 @@ static void collectMeasureEvents(EventMap* events, Measure* m, Part* part, int t if (e->type() == Element::PEDAL) { Segment* s1 = static_cast(e->startElement()); Segment* s2 = static_cast(e->endElement()); + if (s2 == 0) { + qDebug("CollectMeasureEvents: spanner %s: no end element at measure %d, staff %d", + e->name(), s1->measure()->no(), e->staffIdx()); + continue; + } Staff* staff = e->staff(); int channel = staff->channel(s1->tick(), 0); diff --git a/libmscore/scorefile.cpp b/libmscore/scorefile.cpp index 837cc51c1bc50..70a3f83666de9 100644 --- a/libmscore/scorefile.cpp +++ b/libmscore/scorefile.cpp @@ -962,42 +962,66 @@ bool Score::read(const QDomElement& de) // check slurs foreach(Spanner* s, spanner) { + if (!s->startElement() || !s->endElement()) { + qDebug("remove incomplete Spanner %s", s->name()); + switch (s->anchor()) { + case Spanner::ANCHOR_SEGMENT: { + if (s->startElement()) { + Segment* seg = static_cast(s->startElement()); + seg->removeSpannerFor(s); + } + if (s->endElement()) { + Segment* seg = static_cast(s->endElement()); + seg->removeSpannerBack(s); + } + Segment* seg = static_cast(s->parent()); + if (seg->isEmpty()) + seg->measure()->remove(seg); + delete s; + } + break; + case Spanner::ANCHOR_CHORD: + if (s->startElement()) { + ChordRest* cr = static_cast(s->startElement()); + cr->removeSpannerFor(s); + } + if (s->endElement()) { + ChordRest* cr = static_cast(s->endElement()); + cr->removeSpannerBack(s); + } + delete s; + break; + + case Spanner::ANCHOR_NOTE: + case Spanner::ANCHOR_MEASURE: + break; + } + continue; + } if (s->type() != Element::SLUR) continue; + Slur* slur = static_cast(s); - if (!slur->startElement() || !slur->endElement()) { - qDebug("incomplete Slur\n"); - if (slur->startElement()) { - qDebug(" front %d\n", static_cast(slur->startElement())->tick()); - static_cast(slur->startElement())->removeSlurFor(slur); - } - if (slur->endElement()) { - qDebug(" back %d\n", static_cast(slur->endElement())->tick()); - static_cast(slur->endElement())->removeSlurBack(slur); - } + ChordRest* cr1 = (ChordRest*)(slur->startElement()); + ChordRest* cr2 = (ChordRest*)(slur->endElement()); + if (cr1->tick() > cr2->tick()) { + qDebug("Slur invalid start-end tick %d-%d\n", cr1->tick(), cr2->tick()); + slur->setStartElement(cr2); + slur->setEndElement(cr1); } - else { - ChordRest* cr1 = (ChordRest*)(slur->startElement()); - ChordRest* cr2 = (ChordRest*)(slur->endElement()); - if (cr1->tick() > cr2->tick()) { - qDebug("Slur invalid start-end tick %d-%d\n", cr1->tick(), cr2->tick()); - slur->setStartElement(cr2); - slur->setEndElement(cr1); - } - int n1 = 0; - int n2 = 0; - foreach(Spanner* s, cr1->spannerFor()) { - if (s == slur) - ++n1; - } - foreach(Spanner* s, cr2->spannerBack()) { - if (s == slur) - ++n2; - } - if (n1 != 1 || n2 != 1) { - qDebug("Slur references bad: %d %d\n", n1, n2); - } + int n1 = 0; + int n2 = 0; + foreach(Spanner* s, cr1->spannerFor()) { + if (s == slur) + ++n1; + } + foreach(Spanner* s, cr2->spannerBack()) { + if (s == slur) + ++n2; + } + if (n1 != 1 || n2 != 1) { + qDebug("Slur references bad: %d %d\n", n1, n2); } } spanner.clear(); diff --git a/mscore/debugger.cpp b/mscore/debugger.cpp index 7d2b479c42157..f0833ca0ef1f1 100644 --- a/mscore/debugger.cpp +++ b/mscore/debugger.cpp @@ -552,7 +552,9 @@ void Debugger::updateElement(Element* el) case Element::TIE: ew = new TieView; break; case Element::VOLTA: ew = new VoltaView; break; case Element::VOLTA_SEGMENT: ew = new VoltaSegmentView; break; - case Element::TEXTLINE: ew = new TextLineView; break; + case Element::PEDAL: + case Element::TEXTLINE: ew = new TextLineView; break; + case Element::PEDAL_SEGMENT: case Element::TEXTLINE_SEGMENT: ew = new TextLineSegmentView; break; case Element::LYRICS: ew = new LyricsView; break; case Element::BEAM: ew = new BeamView; break;