Skip to content

Commit

Permalink
Merge pull request #3595 from mattmcclinch/270990-fermatas-over-barlines
Browse files Browse the repository at this point in the history
fix #270990: Unable to add fermatas to bar lines
  • Loading branch information
anatoly-os committed Feb 16, 2019
1 parent b2bbf74 commit a0cdc93
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 22 deletions.
24 changes: 23 additions & 1 deletion libmscore/barline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "stafflines.h"
#include "spanner.h"
#include "undo.h"
#include "fermata.h"

namespace Ms {

Expand Down Expand Up @@ -584,7 +585,7 @@ bool BarLine::acceptDrop(EditData& data) const
return true;
}
else {
return (type == ElementType::ARTICULATION
return ((type == ElementType::ARTICULATION || type == ElementType::FERMATA)
&& segment()
&& segment()->isEndBarLineType());
}
Expand Down Expand Up @@ -646,6 +647,27 @@ Element* BarLine::drop(EditData& data)
score()->undoAddElement(atr);
return atr;
}
else if (e->isFermata()) {
e->setPlacement(track() & 1 ? Placement::BELOW : Placement::ABOVE);
for (Element* el: segment()->annotations())
if (el->isFermata() && (el->track() == track())) {
if (el->subtype() == e->subtype()) {
delete e;
return el;
}
else {
e->setPlacement(el->placement());
e->setTrack(track());
e->setParent(segment());
score()->undoChangeElement(el, e);
return e;
}
}
e->setTrack(track());
e->setParent(segment());
score()->undoAddElement(e);
return e;
}
return 0;
}

Expand Down
4 changes: 3 additions & 1 deletion libmscore/edit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4278,7 +4278,9 @@ void Score::undoAddElement(Element* element)
Segment* segment = toSegment(element->parent());
int tick = segment->tick();
Measure* m = score->tick2measure(tick);
Segment* seg = m->undoGetSegment(SegmentType::ChordRest, tick);
if ((segment->segmentType() == SegmentType::EndBarLine) && (m->tick() == tick))
m = m->prevMeasure();
Segment* seg = m->undoGetSegment(segment->segmentType(), tick);
ne->setTrack(ntrack);
ne->setParent(seg);
undo(new AddElement(ne));
Expand Down
5 changes: 2 additions & 3 deletions libmscore/layout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3484,9 +3484,8 @@ void Score::layoutSystemElements(System* system, LayoutContext& lc)
Measure* m = toMeasure(mb);
m->layoutMeasureNumber();
for (Segment* s = m->first(); s; s = s->next()) {
if (!s->isChordRestType())
continue;
sl.push_back(s);
if (s->isChordRestType() || !s->annotations().empty())
sl.push_back(s);
}
}

Expand Down
28 changes: 25 additions & 3 deletions libmscore/measure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "drumset.h"
#include "duration.h"
#include "dynamic.h"
#include "fermata.h"
#include "fret.h"
#include "glissando.h"
#include "hairpin.h"
Expand Down Expand Up @@ -2037,6 +2038,7 @@ void Measure::readVoice(XmlReader& e, int staffIdx, bool irregular)
QList<Chord*> graceNotes;
Beam* startingBeam = nullptr;
Tuplet* tuplet = nullptr;
Fermata* fermata = nullptr;

Staff* staff = score()->staff(staffIdx);
Fraction timeStretch(staff->timeStretch(tick()));
Expand Down Expand Up @@ -2082,6 +2084,10 @@ void Measure::readVoice(XmlReader& e, int staffIdx, bool irregular)
segment->add(barLine);
barLine->layout();
}
if (fermata) {
segment->add(fermata);
fermata = nullptr;
}
}
else if (tag == "Chord") {
Chord* chord = new Chord(score());
Expand All @@ -2107,6 +2113,10 @@ void Measure::readVoice(XmlReader& e, int staffIdx, bool irregular)
int crticks = chord->actualTicks();
e.incTick(crticks);
}
if (fermata) {
segment->add(fermata);
fermata = nullptr;
}
}
else if (tag == "Rest") {
Rest* rest = new Rest(score());
Expand All @@ -2122,6 +2132,10 @@ void Measure::readVoice(XmlReader& e, int staffIdx, bool irregular)
rest->readAddTuplet(tuplet);
segment = getSegment(SegmentType::ChordRest, e.tick());
segment->add(rest);
if (fermata) {
segment->add(fermata);
fermata = nullptr;
}

if (!rest->duration().isValid()) // hack
rest->setDuration(timesig()/timeStretch);
Expand Down Expand Up @@ -2258,18 +2272,21 @@ void Measure::readVoice(XmlReader& e, int staffIdx, bool irregular)
|| tag == "InstrumentChange"
|| tag == "StaffState"
|| tag == "FiguredBass"
|| tag == "Fermata"
) {
Element* el = Element::name2Element(tag, score());
// hack - needed because tick tags are unreliable in 1.3 scores
// for symbols attached to anything but a measure
el->setTrack(e.track());
if (el->isFermata())
el->setPlacement(el->track() & 1 ? Placement::BELOW : Placement::ABOVE);
el->read(e);
segment = getSegment(SegmentType::ChordRest, e.tick());
segment->add(el);
}
else if (tag == "Fermata") {
fermata = new Fermata(score());
fermata->setTrack(e.track());
fermata->setPlacement(fermata->track() & 1 ? Placement::BELOW : Placement::ABOVE);
fermata->read(e);
}
else if (tag == "Image") {
if (MScore::noImages)
e.skipCurrentElement();
Expand Down Expand Up @@ -2345,6 +2362,11 @@ void Measure::readVoice(XmlReader& e, int staffIdx, bool irregular)
delete tuplet;
}
}
if (fermata) {
segment = getSegment(SegmentType::EndBarLine, e.tick());
segment->add(fermata);
fermata = nullptr;
}
}

//---------------------------------------------------------
Expand Down
4 changes: 2 additions & 2 deletions libmscore/read114.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1054,7 +1054,7 @@ static void readChord(Measure* m, Chord* chord, XmlReader& e)
chord->add(note);
}
else if (tag == "Attribute" || tag == "Articulation") {
Element* el = readArticulation(chord, e);
Element* el = readArticulation(chord->score(), e);
if (el->isFermata()) {
if (!chord->segment())
chord->setParent(m->getSegment(SegmentType::ChordRest, e.tick()));
Expand Down Expand Up @@ -1087,7 +1087,7 @@ static void readRest(Measure* m, Rest* rest, XmlReader& e)
while (e.readNextStartElement()) {
const QStringRef& tag(e.name());
if (tag == "Attribute" || tag == "Articulation") {
Element* el = readArticulation(rest, e);
Element* el = readArticulation(rest->score(), e);
if (el->isFermata()) {
if (!rest->segment())
rest->setParent(m->getSegment(SegmentType::ChordRest, e.tick()));
Expand Down
37 changes: 26 additions & 11 deletions libmscore/read206.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1922,7 +1922,7 @@ bool readChordRestProperties206(XmlReader& e, ChordRest* ch)
ch->setBeamMode(bm);
}
else if (tag == "Articulation") {
Element* el = readArticulation(ch, e);
Element* el = readArticulation(ch->score(), e);
if (el->isFermata())
ch->segment()->add(el);
else
Expand Down Expand Up @@ -2526,12 +2526,13 @@ static void setFermataPlacement(Element* el, ArticulationAnchor anchor, Directio
// readArticulation
//---------------------------------------------------------

Element* readArticulation(ChordRest* cr, XmlReader& e)
Element* readArticulation(Score* score, XmlReader& e)
{
Element* el = 0;
SymId sym = SymId::fermataAbove; // default -- backward compatibility (no type = ufermata in 1.2)
ArticulationAnchor anchor = ArticulationAnchor::TOP_STAFF;
Direction direction = Direction::AUTO;
int track = e.track();
double timeStretch = 0.0;
bool useDefaultPlacement = true;

Expand Down Expand Up @@ -2583,7 +2584,7 @@ Element* readArticulation(ChordRest* cr, XmlReader& e)
sym = al[i].id;
bool up = al[i].up;
direction = up ? Direction::UP : Direction::DOWN;
if ((direction == Direction::DOWN) != (cr->track() & 1))
if ((direction == Direction::DOWN) != (track & 1))
useDefaultPlacement = false;
break;
}
Expand All @@ -2604,10 +2605,10 @@ Element* readArticulation(ChordRest* cr, XmlReader& e)
case SymId::fermataLongBelow:
case SymId::fermataVeryLongAbove:
case SymId::fermataVeryLongBelow:
el = new Fermata(sym, cr->score());
el = new Fermata(sym, score);
break;
default:
el = new Articulation(sym, cr->score());
el = new Articulation(sym, score);
toArticulation(el)->setDirection(direction);
break;
};
Expand Down Expand Up @@ -2639,16 +2640,16 @@ Element* readArticulation(ChordRest* cr, XmlReader& e)
}
// Special case for "no type" = ufermata, with missing subtype tag
if (!el)
el = new Fermata(sym, cr->score());
el = new Fermata(sym, score);
if (el->isFermata()) {
if (timeStretch != 0.0)
el->setProperty(Pid::TIME_STRETCH, timeStretch);
if (useDefaultPlacement)
el->setPlacement(cr->track() & 1 ? Placement::BELOW : Placement::ABOVE);
el->setPlacement(track & 1 ? Placement::BELOW : Placement::ABOVE);
else
setFermataPlacement(el, anchor, direction);
}
el->setTrack(cr->track());
el->setTrack(track);
return el;
}

Expand Down Expand Up @@ -2775,6 +2776,8 @@ static void readMeasure(Measure* m, int staffIdx, XmlReader& e)
lastTick = e.tick();
}
else if (tag == "BarLine") {
Fermata* fermataAbove = nullptr;
Fermata* fermataBelow = nullptr;
BarLine* bl = new BarLine(score);
bl->setTrack(e.track());
while (e.readNextStartElement()) {
Expand All @@ -2796,9 +2799,17 @@ static void readMeasure(Measure* m, int staffIdx, XmlReader& e)
else if (t == "spanToOffset")
bl->setSpanTo(e.readInt());
else if (t == "Articulation") {
Articulation* a = new Articulation(score);
a->read(e);
bl->add(a);
Element* el = readArticulation(score, e);
if (el->isFermata()) {
if (el->placement() == Placement::ABOVE)
fermataAbove = toFermata(el);
else {
fermataBelow = toFermata(el);
fermataBelow->setTrack((bl->staffIdx() + bl->spanStaff()) * VOICES);
}
}
else
bl->add(el);
}
else if (!bl->Element::readProperties(e))
e.unknown();
Expand All @@ -2821,6 +2832,10 @@ static void readMeasure(Measure* m, int staffIdx, XmlReader& e)
segment = m->getSegment(st, e.tick());
segment->add(bl);
bl->layout();
if (fermataAbove)
segment->add(fermataAbove);
if (fermataBelow)
segment->add(fermataBelow);
}
else if (tag == "Chord") {
Chord* chord = new Chord(score);
Expand Down
2 changes: 1 addition & 1 deletion libmscore/read206.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class PageFormat {
qreal oddRightMargin() const { return _size.width() - _printableWidth - _oddLeftMargin; }
};

extern Element* readArticulation(ChordRest*, XmlReader&);
extern Element* readArticulation(Score*, XmlReader&);
extern void readAccidental206(Accidental*, XmlReader&);
extern void setPageFormat(MStyle*, const PageFormat&);
extern void initPageFormat(MStyle*, PageFormat*);
Expand Down

0 comments on commit a0cdc93

Please sign in to comment.