Skip to content

Commit

Permalink
fix #291698: ensure consistent state of two-notes tremolo after file …
Browse files Browse the repository at this point in the history
…reading
  • Loading branch information
dmitrio95 committed Jul 6, 2019
1 parent 98959bd commit 754ddfd
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 47 deletions.
48 changes: 1 addition & 47 deletions libmscore/layout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2549,52 +2549,6 @@ void layoutDrumsetChord(Chord* c, const Drumset* drumset, const StaffType* st, q
}
}

//---------------------------------------------------------
// connectTremolo
// Connect two-notes tremolo and update duration types
// for the involved chords.
//---------------------------------------------------------

static void connectTremolo(Measure* m)
{
const int ntracks = m->score()->ntracks();
constexpr SegmentType st = SegmentType::ChordRest;
for (Segment* s = m->first(st); s; s = s->next(st)) {
for (int i = 0; i < ntracks; ++i) {
Element* e = s->element(i);
if (!e || !e->isChord())
continue;

Chord* c = toChord(e);
Tremolo* tremolo = c->tremolo();
if (tremolo && tremolo->twoNotes()) {
// Ensure correct duration type for chord
c->setDurationType(tremolo->durationType());

// If it is the first tremolo's chord, find the second
// chord for tremolo, if needed.
if (!tremolo->chord1())
tremolo->setChords(c, tremolo->chord2());
else if (tremolo->chord1() != c || tremolo->chord2())
continue;

for (Segment* ls = s->next(st); ls; ls = ls->next(st)) {
if (Element* element = ls->element(i)) {
if (!element->isChord()) {
qDebug("cannot connect tremolo");
continue;
}
Chord* nc = toChord(element);
tremolo->setChords(c, nc);
nc->setTremolo(tremolo);
break;
}
}
}
}
}
}

//---------------------------------------------------------
// getNextMeasure
//---------------------------------------------------------
Expand Down Expand Up @@ -2670,7 +2624,7 @@ void Score::getNextMeasure(LayoutContext& lc)
return;
}

connectTremolo(measure);
measure->connectTremolo();

//
// calculate accidentals and note lines,
Expand Down
48 changes: 48 additions & 0 deletions libmscore/measure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2054,6 +2054,8 @@ void Measure::read(XmlReader& e, int staffIdx)
e.setTick(lm->tick() + lm->ticks());
}
e.setCurrentMeasure(nullptr);

connectTremolo();
}

//---------------------------------------------------------
Expand Down Expand Up @@ -2523,6 +2525,52 @@ void Measure::scanElements(void* data, void (*func)(void*, Element*), bool all)
}
}

//---------------------------------------------------------
// connectTremolo
/// Connect two-notes tremolo and update duration types
/// for the involved chords.
//---------------------------------------------------------

void Measure::connectTremolo()
{
const int ntracks = score()->ntracks();
constexpr SegmentType st = SegmentType::ChordRest;
for (Segment* s = first(st); s; s = s->next(st)) {
for (int i = 0; i < ntracks; ++i) {
Element* e = s->element(i);
if (!e || !e->isChord())
continue;

Chord* c = toChord(e);
Tremolo* tremolo = c->tremolo();
if (tremolo && tremolo->twoNotes()) {
// Ensure correct duration type for chord
c->setDurationType(tremolo->durationType());

// If it is the first tremolo's chord, find the second
// chord for tremolo, if needed.
if (!tremolo->chord1())
tremolo->setChords(c, tremolo->chord2());
else if (tremolo->chord1() != c || tremolo->chord2())
continue;

for (Segment* ls = s->next(st); ls; ls = ls->next(st)) {
if (Element* element = ls->element(i)) {
if (!element->isChord()) {
qDebug("cannot connect tremolo");
continue;
}
Chord* nc = toChord(element);
tremolo->setChords(c, nc);
nc->setTremolo(tremolo);
break;
}
}
}
}
}
}

//---------------------------------------------------------
// createVoice
// Create a voice on demand by filling the measure
Expand Down
1 change: 1 addition & 0 deletions libmscore/measure.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ class Measure final : public MeasureBase {
Segment* undoGetSegment(SegmentType st, const Fraction& f) { return undoGetSegmentR(st, f - tick()); }
Segment* getSegment(SegmentType st, const Fraction& f) { return getSegmentR(st, f - tick()); }

void connectTremolo();

qreal createEndBarLines(bool);
void barLinesSetSpan(Segment*);
Expand Down
1 change: 1 addition & 0 deletions libmscore/read114.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2171,6 +2171,7 @@ static void readMeasure(Measure* m, int staffIdx, XmlReader& e)
}
}
e.checkTuplets();
m->connectTremolo();
}

//---------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions libmscore/read206.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3360,6 +3360,7 @@ static void readMeasure(Measure* m, int staffIdx, XmlReader& e)
e.unknown();
}
e.checkTuplets();
m->connectTremolo();
}

//---------------------------------------------------------
Expand Down

0 comments on commit 754ddfd

Please sign in to comment.