Skip to content

Commit

Permalink
fix #44676: Change of duration of measures including grace notes (acc…
Browse files Browse the repository at this point in the history
…iaccatura) causes a crash in tab staff
  • Loading branch information
wschweer committed Jan 21, 2015
1 parent 4516685 commit 69febbc
Show file tree
Hide file tree
Showing 11 changed files with 95 additions and 120 deletions.
58 changes: 37 additions & 21 deletions libmscore/beam.cpp
Expand Up @@ -268,7 +268,7 @@ void Beam::layout1()
slope = 0.0;
_cross = false;
minMove = maxMove = 0; // no cross-beaming in TAB's!
foreach(ChordRest* cr, _elements) {
foreach (ChordRest* cr, _elements) {
if (cr->type() == Element::Type::CHORD) {
// set members maxDuration, c1, c2
if (!maxDuration.isValid() || (maxDuration < cr->durationType()))
Expand Down Expand Up @@ -403,16 +403,24 @@ void Beam::layoutGraceNotes()
//
// determine beam stem direction
//
if (_direction != MScore::Direction::AUTO)
_up = _direction == MScore::Direction::UP;
if (staff()->isTabStaff()) {
//TABULATURES: all beams (and related chords) are:
// UP or DOWN according to TAB duration position
// slope 0
_up = !staff()->staffType()->stemsDown();
}
else {
ChordRest* cr = _elements[0];
if (_direction != MScore::Direction::AUTO)
_up = _direction == MScore::Direction::UP;
else {
ChordRest* cr = _elements[0];

Measure* m = cr->measure();
if (m->hasVoices(cr->staffIdx()))
_up = !(cr->voice() % 2);
else
_up = true;
Measure* m = cr->measure();
if (m->hasVoices(cr->staffIdx()))
_up = !(cr->voice() % 2);
else
_up = true;
}
}

int idx = (_direction == MScore::Direction::AUTO || _direction == MScore::Direction::DOWN) ? 0 : 1;
Expand Down Expand Up @@ -1705,14 +1713,18 @@ void Beam::layout2(QList<ChordRest*>crl, SpannerSegmentType, int frag)
Chord* c = static_cast<Chord*>(cr);
if (c->type() != Element::Type::CHORD)
continue;
c->layoutStem1();
Stem* stem = c->stem();
#if 0
if (!stem) {
// is this ever true?
qDebug("create stem in layout beam");
// is this ever true? -> yes
qDebug("create stem in layout beam, track %d", c->track());
stem = new Stem(score());
c->setStem(stem);
stem->setParent(c);
score()->undoAddElement(stem);
// stem->rypos() = (c->up() ? c->downNote() : c->upNote())->rypos();
}
#endif
if (c->hook())
score()->undoRemoveElement(c->hook());

Expand All @@ -1739,7 +1751,8 @@ void Beam::layout2(QList<ChordRest*>crl, SpannerSegmentType, int frag)
beamSegments.back()->x2());
}
}
stem->setLen(y2 - (by + _pagePos.y()));
if (stem)
stem->setLen(y2 - (by + _pagePos.y()));

#if 0 // TODO ??
if (!tab) {
Expand All @@ -1756,20 +1769,23 @@ void Beam::layout2(QList<ChordRest*>crl, SpannerSegmentType, int frag)
}
#endif


//
// layout stem slash for acciacatura
//
if ((c == crl.front()) && c->noteType() == NoteType::ACCIACCATURA) {
StemSlash* stemSlash = c->stemSlash();
if (!stemSlash) {
stemSlash = new StemSlash(score());
c->add(stemSlash);
}
stemSlash->layout();
// if (!stemSlash)
// c->add(new StemSlash(score()));
if (stemSlash)
stemSlash->layout();
}
else
c->setStemSlash(0);

#if 0
else {
if (c->stemSlash())
c->remove(c->stemSlash());
}
#endif
Tremolo* tremolo = c->tremolo();
if (tremolo)
tremolo->layout();
Expand Down
94 changes: 36 additions & 58 deletions libmscore/chord.cpp
Expand Up @@ -237,9 +237,9 @@ Chord::Chord(const Chord& c, bool link)
add(new Stem(*(c._stem)));
if (c._hook)
add(new Hook(*(c._hook)));
if (c._stemSlash)
if (c._stemSlash) {
add(new StemSlash(*(c._stemSlash)));

}
if (c._glissando) {
Glissando* g = new Glissando(*(c._glissando));
add(g);
Expand Down Expand Up @@ -319,20 +319,6 @@ Chord::~Chord()
qDeleteAll(_notes);
}

//---------------------------------------------------------
// setStem
//---------------------------------------------------------

void Chord::setStem(Stem* s)
{
delete _stem;
_stem = s;
if (_stem) {
_stem->setParent(this);
_stem->setTrack(track());
}
}

//---------------------------------------------------------
// stemPosX
// return Chord coordinates
Expand Down Expand Up @@ -476,6 +462,7 @@ void Chord::add(Element* e)
_glissando = static_cast<Glissando*>(e);
break;
case Element::Type::STEM:
Q_ASSERT(!_stem);
_stem = static_cast<Stem*>(e);
break;
case Element::Type::HOOK:
Expand All @@ -485,6 +472,7 @@ void Chord::add(Element* e)
_el.push_back(e);
break;
case Element::Type::STEM_SLASH:
Q_ASSERT(!_stemSlash);
_stemSlash = static_cast<StemSlash*>(e);
break;
case Element::Type::CHORD:
Expand Down Expand Up @@ -565,6 +553,10 @@ void Chord::remove(Element* e)
_hook = 0;
break;
case Element::Type::STEM_SLASH:
Q_ASSERT(_stemSlash);
if (_stemSlash->selected() && score())
score()->deselect(_stemSlash);
delete _stemSlash;
_stemSlash = 0;
break;
case Element::Type::CHORDLINE:
Expand Down Expand Up @@ -999,9 +991,9 @@ void Chord::read(XmlReader& e)
else if (ChordRest::readProperties(e))
;
else if (tag == "Stem") {
_stem = new Stem(score());
_stem->read(e);
add(_stem);
Stem* s = new Stem(score());
s->read(e);
add(s);
}
else if (tag == "Hook") {
_hook = new Hook(score());
Expand Down Expand Up @@ -1142,10 +1134,9 @@ qreal Chord::centerX() const

void Chord::scanElements(void* data, void (*func)(void*, Element*), bool all)
{
bool slash = _noStem || (measure() && measure()->slashStyle(staffIdx()));
if (_hook && !slash)
if (_hook)
func(data, _hook );
if (_stem && !slash)
if (_stem)
func(data, _stem);
if (_stemSlash)
func(data, _stemSlash);
Expand Down Expand Up @@ -1227,32 +1218,32 @@ void Chord::setScore(Score* s)

void Chord::layoutStem1()
{
bool hasStem = durationType().hasStem() && !(_noStem || measure()->slashStyle(staffIdx()));

if (hasStem) {
if (durationType().hasStem() && !(_noStem || measure()->slashStyle(staffIdx())
|| (staff() && staff()->isTabStaff() && staff()->staffType()->slashStyle()))) {
if (!_stem) {
Stem* stem = new Stem(score());
stem->setParent(this);
stem->setGenerated(true);
score()->undoAddElement(stem);
}
}
else if (_stem)
score()->undoRemoveElement(_stem);

if (hasStem && (_noteType == NoteType::ACCIACCATURA)) {
if (_stemSlash == 0) {
StemSlash* slash = new StemSlash(score());
add(slash);

// slash->setParent(this);
// slash->setGenerated(true);
// score()->undoAddElement(slash);
if (_noteType == NoteType::ACCIACCATURA) {
if (beam() && beam()->elements().front() == this) {
if (!_stemSlash)
add(new StemSlash(score()));
}
else {
if (_stemSlash)
remove(_stemSlash);
}
}
}
else if (_stemSlash)
// score()->undoRemoveElement(_stemSlash);
setStemSlash(0);
else {
if (_stem)
score()->undoRemoveElement(_stem);
if (_stemSlash)
remove(_stemSlash);
}

}

//---------------------------------------------------------
Expand Down Expand Up @@ -2126,8 +2117,11 @@ void Chord::layoutTablature()
// if stem is required but missing, add it;
// set stem position (stem length is set in Chord:layoutStem() )
else {
if (_stem == 0)
setStem(new Stem(score()));
if (_stem == 0) {
Stem* stem = new Stem(score());
stem->setParent(this);
score()->undo(new AddElement(stem));
}
_stem->setPos(tab->chordStemPos(this) * _spatium);
if (_hook) {
if (beam())
Expand All @@ -2139,10 +2133,6 @@ void Chord::layoutTablature()
}
}
}
// unconditionally delete grace slashes
delete _stemSlash;
_stemSlash = 0;

if (!tab->genDurations() // if tab is not set for duration symbols
|| track2voice(track()) // or not in first voice
|| isGrace()) { // or chord is a grace (no dur. symbols for graces
Expand Down Expand Up @@ -2758,18 +2748,6 @@ void Chord::reset()
ChordRest::reset();
}

//---------------------------------------------------------
// setStemSlash
//---------------------------------------------------------

void Chord::setStemSlash(StemSlash* s)
{
if (_stemSlash && _stemSlash->selected())
score()->selection().remove(_stemSlash);
delete _stemSlash;
_stemSlash = s;
}

//---------------------------------------------------------
// slash
//---------------------------------------------------------
Expand Down
2 changes: 0 additions & 2 deletions libmscore/chord.h
Expand Up @@ -143,13 +143,11 @@ class Chord : public ChordRest {
Note* findNote(int pitch) const;

Stem* stem() const { return _stem; }
void setStem(Stem* s);
Arpeggio* arpeggio() const { return _arpeggio; }
Tremolo* tremolo() const { return _tremolo; }
void setTremolo(Tremolo* t) { _tremolo = t; }
Glissando* glissando() const { return _glissando; }
StemSlash* stemSlash() const { return _stemSlash; }
void setStemSlash(StemSlash* s);
bool slash();
void setSlash(bool flag, bool stemless);

Expand Down
6 changes: 5 additions & 1 deletion libmscore/layout.cpp
Expand Up @@ -1163,8 +1163,12 @@ void Score::layoutStage2()
bool crossMeasure = styleB(StyleIdx::crossMeasureValues);

for (int track = 0; track < tracks; ++track) {
if (!staff(track2staff(track))->show())
Staff* stf = staff(track2staff(track));

// dont compute beams for invisible staffs and tablature in slash style
if (!stf->show() || (stf->isTabStaff() && stf->staffType()->slashStyle()))
continue;

ChordRest* a1 = 0; // start of (potential) beam
Beam* beam = 0; // current beam
Measure* measure = 0;
Expand Down
21 changes: 0 additions & 21 deletions libmscore/measure.cpp
Expand Up @@ -299,27 +299,6 @@ struct AcEl {
qreal x;
};

#if 0
//---------------------------------------------------------
// layoutChords0
//---------------------------------------------------------

void Measure::layoutChords0(Segment* segment, int startTrack)
{
int staffIdx = startTrack/VOICES;
Staff* staff = score()->staff(staffIdx);
qreal staffMag = staff->mag();

int endTrack = startTrack + VOICES;
for (int track = startTrack; track < endTrack; ++track) {
ChordRest* cr = static_cast<ChordRest*>(segment->element(track));
if (!cr)
continue;
layoutCR0(cr, staffMag);
}
}
#endif

//---------------------------------------------------------
// layoutCR0
//---------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion libmscore/stafftype.h
Expand Up @@ -162,7 +162,7 @@ class StaffType {
bool _showRests = false; // whether to draw rests or not
bool _stemsDown = true; // stems are drawn downward (stem-and-beam durations only)
bool _stemsThrough = true; // stems are drawn through the staff rather than beside it (stem-and-beam durations only)
bool _upsideDown = false; // whether lines are drwan with highest string at top (false) or at bottom (true)
bool _upsideDown = false; // whether lines are drawn with highest string at top (false) or at bottom (true)
bool _useNumbers = true; // true: use numbers ('0' - ...) for frets | false: use letters ('a' - ...)

// internally managed variables
Expand Down
3 changes: 1 addition & 2 deletions libmscore/stem.cpp
Expand Up @@ -145,11 +145,10 @@ void Stem::draw(QPainter* painter) const
Staff* st = staff();
bool useTab = st && st->isTabStaff();

if (useTab && st->staffType()->slashStyle())
return;
qreal lw = lineWidth();
painter->setPen(QPen(curColor(), lw, Qt::SolidLine, Qt::RoundCap));
painter->drawLine(line);

if (!useTab || !chord())
return;

Expand Down
1 change: 0 additions & 1 deletion libmscore/undo.cpp
Expand Up @@ -1572,7 +1572,6 @@ const char* AddElement::name() const
}
#endif


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

0 comments on commit 69febbc

Please sign in to comment.