Skip to content

Commit

Permalink
Merge pull request #2352 from lasconic/fix-81731
Browse files Browse the repository at this point in the history
fix #81731: Crash when repeatedly pressing Shift+A
  • Loading branch information
lasconic committed Jan 22, 2016
2 parents 439bd74 + 9f05f02 commit 9961e11
Show file tree
Hide file tree
Showing 12 changed files with 858 additions and 14 deletions.
4 changes: 4 additions & 0 deletions libmscore/cmd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,10 @@ void Score::cmdAddInterval(int val, const QList<Note*>& nl)
ntpc1 = on->tpc1();
ntpc2 = on->tpc2();
}
if (npitch < 0 || npitch > 127) {
delete note;
return;
}
note->setPitch(npitch, ntpc1, ntpc2);

undoAddElement(note);
Expand Down
9 changes: 7 additions & 2 deletions libmscore/edit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1011,7 +1011,9 @@ NoteVal Score::noteValForPosition(Position pos, bool &error)
}

case StaffGroup::STANDARD: {
AccidentalVal acci = s->measure()->findAccidental(s, staffIdx, line);
AccidentalVal acci = s->measure()->findAccidental(s, staffIdx, line, error);
if (error)
return nval;
int step = absStep(line, clef);
int octave = step/7;
nval.pitch = step2pitch(step) + octave * 12 + int(acci);
Expand Down Expand Up @@ -1308,7 +1310,10 @@ void Score::repitchNote(const Position& p, bool replace)
ClefType clef = st->clef(tick);

NoteVal nval;
AccidentalVal acci = s->measure()->findAccidental(s, p.staffIdx, p.line);
bool error = false;
AccidentalVal acci = s->measure()->findAccidental(s, p.staffIdx, p.line, error);
if (error)
return;
int step = absStep(p.line, clef);
int octave = step / 7;
nval.pitch = step2pitch(step) + octave * 12 + int(acci);
Expand Down
18 changes: 14 additions & 4 deletions libmscore/key.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,19 +177,29 @@ void KeySigEvent::initFromSubtype(int st)
// accidentalVal
//---------------------------------------------------------

AccidentalVal AccidentalState::accidentalVal(int line) const
AccidentalVal AccidentalState::accidentalVal(int line, bool &error) const
{
Q_ASSERT(line >= 0 && line < 75);
if (line < MIN_ACC_STATE || line >= MAX_ACC_STATE) {
error = true;
return AccidentalVal::NATURAL;
}
return AccidentalVal((state[line] & 0x0f) - 2);
}

AccidentalVal AccidentalState::accidentalVal(int line) const
{
Q_ASSERT(line >= MIN_ACC_STATE && line < MAX_ACC_STATE);
bool error = false;
return accidentalVal(line, error);
}

//---------------------------------------------------------
// tieContext
//---------------------------------------------------------

bool AccidentalState::tieContext(int line) const
{
Q_ASSERT(line >= 0 && line < 75);
Q_ASSERT(line >= MIN_ACC_STATE && line < MAX_ACC_STATE);
return state[line] & TIE_CONTEXT;
}

Expand All @@ -199,7 +209,7 @@ bool AccidentalState::tieContext(int line) const

void AccidentalState::setAccidentalVal(int line, AccidentalVal val, bool tieContext)
{
Q_ASSERT(line >= 0 && line < 75);
Q_ASSERT(line >= MIN_ACC_STATE && line < MAX_ACC_STATE);
// casts needed to work around a bug in Xcode 4.2 on Mac, see #25910
Q_ASSERT(int(val) >= int(AccidentalVal::FLAT2) && int(val) <= int(AccidentalVal::SHARP2));
state[line] = (int(val) + 2) | (tieContext ? TIE_CONTEXT : 0);
Expand Down
5 changes: 4 additions & 1 deletion libmscore/key.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,16 @@ class KeySigEvent {
//---------------------------------------------------------

static const int TIE_CONTEXT = 0x10;
static const int MIN_ACC_STATE = 0;
static const int MAX_ACC_STATE = 75;

class AccidentalState {
uchar state[75]; // (0 -- 4) | TIE_CONTEXT
uchar state[MAX_ACC_STATE]; // (0 -- 4) | TIE_CONTEXT

public:
AccidentalState() {}
void init(Key key);
AccidentalVal accidentalVal(int line, bool &error) const;
AccidentalVal accidentalVal(int line) const;
bool tieContext(int line) const;
void setAccidentalVal(int line, AccidentalVal val, bool tieContext = false);
Expand Down
4 changes: 2 additions & 2 deletions libmscore/measure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ AccidentalVal Measure::findAccidental(Note* note) const
/// relative staff line.
//---------------------------------------------------------

AccidentalVal Measure::findAccidental(Segment* s, int staffIdx, int line) const
AccidentalVal Measure::findAccidental(Segment* s, int staffIdx, int line, bool &error) const
{
AccidentalState tversatz; // state of already set accidentals for this measure
Staff* staff = score()->staff(staffIdx);
Expand All @@ -423,7 +423,7 @@ AccidentalVal Measure::findAccidental(Segment* s, int staffIdx, int line) const
if (segment == s && staff->isPitchedStaff()) {
ClefType clef = staff->clef(s->tick());
int l = relStep(line, clef);
return tversatz.accidentalVal(l);
return tversatz.accidentalVal(l, error);
}
for (int track = startTrack; track < endTrack; ++track) {
Element* e = segment->element(track);
Expand Down
2 changes: 1 addition & 1 deletion libmscore/measure.h
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ class Measure : public MeasureBase {
void resetRepeatFlag(Repeat val) { _repeatFlags = Repeat(int(_repeatFlags) & ~int(val)); }

AccidentalVal findAccidental(Note*) const;
AccidentalVal findAccidental(Segment* s, int staffIdx, int line) const;
AccidentalVal findAccidental(Segment* s, int staffIdx, int line, bool &error) const;
void exchangeVoice(int voice1, int voice2, int staffIdx);
void checkMultiVoices(int staffIdx);
bool hasVoice(int track) const;
Expand Down
6 changes: 5 additions & 1 deletion libmscore/note.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1814,7 +1814,11 @@ void Note::updateAccidental(AccidentalState* as)
AccidentalType acci = AccidentalType::NONE;

AccidentalVal accVal = tpc2alter(tpc());
if ((accVal != as->accidentalVal(relLine)) || hidden() || as->tieContext(relLine)) {
bool error = false;
AccidentalVal relLineAccVal = as->accidentalVal(relLine, error);
if (error)
return;
if ((accVal != relLineAccVal) || hidden() || as->tieContext(relLine)) {
as->setAccidentalVal(relLine, accVal, _tieBack != 0);
if (_tieBack)
acci = AccidentalType::NONE;
Expand Down
5 changes: 3 additions & 2 deletions libmscore/rendermidi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -915,7 +915,7 @@ int articulationExcursion(Note *noteL, Note *noteR, int deltastep)
int lineR2 = convertLine(lineL2, noteL, noteR);
// is there another note in this segment on the same line?
// if so, use its pitch exactly.
int halfsteps;
int halfsteps = 0;
int staffIdx = staffL->idx();
int startTrack = staffIdx * VOICES;
int endTrack = startTrack + VOICES;
Expand All @@ -940,7 +940,8 @@ int articulationExcursion(Note *noteL, Note *noteR, int deltastep)
}
if (!done) {
if (staffL->isPitchedStaff()) {
AccidentalVal acciv2 = measureR->findAccidental(chordR->segment(), chordR->staff()->idx(), lineR2);
bool error = false;
AccidentalVal acciv2 = measureR->findAccidental(chordR->segment(), chordR->staff()->idx(), lineR2, error);
int acci2 = int(acciv2);
// we have to add ( note->ppitch() - noteL->epitch() ) which is the delta for transposing instruments.
halfsteps = line2pitch(lineL-deltastep, clefL, Key::C) + noteL->ppitch() - noteL->epitch() + acci2 - pitchL;
Expand Down
5 changes: 4 additions & 1 deletion mscore/importmxmlpass2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1920,7 +1920,10 @@ static void markUserAccidentals(const int firstStaff,
if (alterMap.contains(nt)) {
int alter = alterMap.value(nt);
int ln = absStep(nt->tpc(), nt->pitch());
AccidentalVal currAccVal = currAcc.accidentalVal(ln);
bool error = false;
AccidentalVal currAccVal = currAcc.accidentalVal(ln, error);
if (error)
continue;
if ((alter == -1
&& currAccVal == AccidentalVal::FLAT
&& nt->accidental()->accidentalType() == AccidentalType::FLAT
Expand Down
Loading

0 comments on commit 9961e11

Please sign in to comment.