Skip to content

Commit

Permalink
remove incomplete spanner when loading corrupted score
Browse files Browse the repository at this point in the history
  • Loading branch information
wschweer committed Dec 10, 2012
1 parent 1e0150d commit 9079e31
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 34 deletions.
1 change: 1 addition & 0 deletions libmscore/measure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2058,6 +2058,7 @@ void Measure::read(const QDomElement& de, int staffIdx)
|| tag == "TextLine"
|| tag == "Volta") {
Spanner* sp = static_cast<Spanner*>(Element::name2Element(tag, score()));
score()->spanner.append(sp);
sp->setTrack(staffIdx * VOICES);
sp->read(e);
segment = getSegment(Segment::SegChordRest, score()->curTick);
Expand Down
1 change: 0 additions & 1 deletion libmscore/measure.h
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand Down
2 changes: 1 addition & 1 deletion libmscore/note.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<Spanner*>(Element::name2Element(tag, score()));
Expand Down
5 changes: 5 additions & 0 deletions libmscore/rendermidi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,11 @@ static void collectMeasureEvents(EventMap* events, Measure* m, Part* part, int t
if (e->type() == Element::PEDAL) {
Segment* s1 = static_cast<Segment*>(e->startElement());
Segment* s2 = static_cast<Segment*>(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);
Expand Down
86 changes: 55 additions & 31 deletions libmscore/scorefile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<Segment*>(s->startElement());
seg->removeSpannerFor(s);
}
if (s->endElement()) {
Segment* seg = static_cast<Segment*>(s->endElement());
seg->removeSpannerBack(s);
}
Segment* seg = static_cast<Segment*>(s->parent());
if (seg->isEmpty())
seg->measure()->remove(seg);
delete s;
}
break;
case Spanner::ANCHOR_CHORD:
if (s->startElement()) {
ChordRest* cr = static_cast<ChordRest*>(s->startElement());
cr->removeSpannerFor(s);
}
if (s->endElement()) {
ChordRest* cr = static_cast<ChordRest*>(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<Slur*>(s);

if (!slur->startElement() || !slur->endElement()) {
qDebug("incomplete Slur\n");
if (slur->startElement()) {
qDebug(" front %d\n", static_cast<ChordRest*>(slur->startElement())->tick());
static_cast<ChordRest*>(slur->startElement())->removeSlurFor(slur);
}
if (slur->endElement()) {
qDebug(" back %d\n", static_cast<ChordRest*>(slur->endElement())->tick());
static_cast<ChordRest*>(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();
Expand Down
4 changes: 3 additions & 1 deletion mscore/debugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 9079e31

Please sign in to comment.