Skip to content

Commit

Permalink
fix #25434
Browse files Browse the repository at this point in the history
  • Loading branch information
wschweer committed Apr 22, 2014
1 parent e89b053 commit 5fb4076
Show file tree
Hide file tree
Showing 12 changed files with 170 additions and 161 deletions.
87 changes: 77 additions & 10 deletions libmscore/chord.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
#include "drumset.h"
#include "key.h"
#include "sym.h"
#include "stringdata.h"

namespace Ms {

Expand Down Expand Up @@ -439,6 +440,10 @@ void Chord::add(Element* e)
_graceNotes.insert(_graceNotes.begin() + idx, gc);
}
break;
case LEDGER_LINE:
qFatal("Chord::add ledgerline\n");
break;

default:
ChordRest::add(e);
break;
Expand All @@ -462,7 +467,7 @@ void Chord::remove(Element* e)
// update accidentals for endNote
Chord* chord = note->tieFor()->endNote()->chord();
Measure* m = chord->segment()->measure();
m->updateAccidentals(chord->staffIdx());
m->cmdUpdateNotes(chord->staffIdx());
}
}
}
Expand Down Expand Up @@ -558,7 +563,8 @@ qreal Chord::maxHeadWidth() const
/// \arg x start x-position
/// \arg len line length
//---------------------------------------------------------
/*

#if 0
void Chord::addLedgerLine(int track, int line, bool visible, qreal x, Spatium len)
{
qreal _spatium = spatium();
Expand Down Expand Up @@ -587,7 +593,8 @@ void Chord::addLedgerLine(int track, int line, bool visible, qreal x, Spatium le
h->setNext(_ledgerLines);
_ledgerLines = h;
}
*/
#endif

//---------------------------------------------------------
// createLedgerLines
/// Creates the ledger lines fro a chord
Expand Down Expand Up @@ -1491,32 +1498,93 @@ void Chord::layout2()
}

//---------------------------------------------------------
// layout10
// updateNotes
//---------------------------------------------------------

void Chord::layout10(AccidentalState* as)
void Chord::updateNotes(AccidentalState* as)
{
for (Chord* c : _graceNotes)
c->layout10(as);
c->updateNotes(as);

Drumset* drumset = 0;
if (staff()->part()->instr()->useDrumset())
drumset = staff()->part()->instr()->drumset();

QList<Note*> nl(notes());
for (Note* note : nl) {
if (drumset) {
if (drumset) {
for (Note* note : nl) {
int pitch = note->pitch();
if (drumset->isValid(pitch)) {
note->setHeadGroup(drumset->noteHead(pitch));
note->setLine(drumset->line(pitch));
}
}
else
}
else {
for (Note* note : nl)
note->layout10(as);
}
sortNotes();
}

//---------------------------------------------------------
// cmdUpdateNotes
//---------------------------------------------------------

void Chord::cmdUpdateNotes(AccidentalState* as)
{
// TAB_STAFF is different, as each note has to be fretted
// in the context of the all of the chords of the whole segment

StaffGroup staffGroup = staff()->staffType()->group();
if (staffGroup == TAB_STAFF_GROUP) {
const Instrument* instrument = staff()->part()->instr();
for (Chord* ch : graceNotes())
instrument->stringData()->fretChords(ch);
instrument->stringData()->fretChords(this);
return;
}

// PITCHED_ and PERCUSSION_STAFF can go note by note

for (Chord* ch : graceNotes()) {
QList<Note*> notes(ch->notes()); // we need a copy!
for (Note* note : notes)
note->updateAccidental(as);
ch->sortNotes();
}

QList<Note*> lnotes(notes()); // we need a copy!
for (Note* note : lnotes) {
if (staffGroup == STANDARD_STAFF_GROUP) {
if (note->tieBack()) {
if (note->accidental() && note->tpc() == note->tieBack()->startNote()->tpc()) {
// TODO: remove accidental only if note is not
// on new system
score()->undoRemoveElement(note->accidental());
}
}
note->updateAccidental(as);
}
else if (staffGroup == PERCUSSION_STAFF_GROUP) {
const Instrument* instrument = staff()->part()->instr();
Drumset* drumset = instrument->drumset();
int pitch = note->pitch();
if (drumset) {
if (!drumset->isValid(pitch)) {
// qDebug("unmapped drum note %d", pitch);
}
else {
note->setHeadGroup(drumset->noteHead(pitch));
note->setLine(drumset->line(pitch));
continue;
}
}
}
}
sortNotes();
}

//---------------------------------------------------------
// layout
//---------------------------------------------------------
Expand Down Expand Up @@ -2424,7 +2492,6 @@ Measure* Chord::measure() const

void Chord::sortNotes()
{
// printf("Chord::sortNotes\n");
std::sort(notes().begin(), notes().end(),
[](const Note* a,const Note* b)->bool { return b->line() < a->line(); }
// [](const Note* a,const Note* b)->bool { return a->pitch() < b->pitch(); }
Expand Down
3 changes: 2 additions & 1 deletion libmscore/chord.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,8 @@ class Chord : public ChordRest {
Note* selectedNote() const;
virtual void layout();
void layout2();
void layout10(AccidentalState*);
void updateNotes(AccidentalState*);
void cmdUpdateNotes(AccidentalState*);

NoteType noteType() const { return _noteType; }
void setNoteType(NoteType t) { _noteType = t; }
Expand Down
2 changes: 1 addition & 1 deletion libmscore/cmd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1386,7 +1386,7 @@ static void changeAccidental2(Note* n, int pitch, int tpc)
// recalculate needed accidentals for
// whole measure
//
chord->measure()->updateAccidentals(staffIdx);
chord->measure()->cmdUpdateNotes(staffIdx);
}

//---------------------------------------------------------
Expand Down
10 changes: 8 additions & 2 deletions libmscore/edit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ Chord* Score::addChord(int tick, TDuration d, Chord* oc, bool genTie, Tuplet* tu
}
}

measure->updateAccidentals(chord->staffIdx());
measure->cmdUpdateNotes(chord->staffIdx());
return chord;
}

Expand Down Expand Up @@ -1111,7 +1111,8 @@ void Score::deleteItem(Element* el)
{
if (!el)
return;
switch(el->type()) {
printf("deleteItem %s\n", el->name());
switch (el->type()) {
case Element::INSTRUMENT_NAME: {
Part* part = el->staff()->part();
InstrumentName* in = static_cast<InstrumentName*>(el);
Expand All @@ -1126,6 +1127,11 @@ void Score::deleteItem(Element* el)
cmdRemoveTimeSig(static_cast<TimeSig*>(el));
break;

case Element::KEYSIG:
undoRemoveElement(el);
cmdUpdateNotes();
break;

case Element::OTTAVA_SEGMENT:
case Element::HAIRPIN_SEGMENT:
case Element::TRILL_SEGMENT:
Expand Down
120 changes: 33 additions & 87 deletions libmscore/measure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -358,29 +358,6 @@ void Measure::layoutCR0(ChordRest* cr, qreal mm)
}
}

//---------------------------------------------------------
// layout10
// computes note lines and accidentals
//---------------------------------------------------------

void Measure::layout10(int staffIdx)
{
AccidentalState as; // state of already set accidentals for this measure
Staff* staff = score()->staff(staffIdx);
as.init(staff->keymap()->key(tick()));
int startTrack = staffIdx * VOICES;
int endTrack = startTrack + VOICES;

for (Segment* s = first(Segment::SegChordRest); s; s = s->next(Segment::SegChordRest)) {
for (int track = startTrack; track < endTrack; ++track) {
Chord* chord = static_cast<Chord*>(s->element(track));
if (!chord || chord->type() != CHORD)
continue;
chord->layout10(&as);
}
}
}

//---------------------------------------------------------
// findAccidental
/// return current accidental value at note position
Expand Down Expand Up @@ -3646,82 +3623,51 @@ void Measure::layoutStage1()
}

//---------------------------------------------------------
// updateAccidentals
// recompute accidentals,
/// undoable add/remove
// updateNotes
// recompute note lines and accidentals
/// not undoable add/remove
//---------------------------------------------------------

void Measure::updateAccidentals(int staffIdx)
void Measure::updateNotes(int staffIdx)
{
Staff* staff = score()->staff(staffIdx);
StaffGroup staffGroup = staff->staffType()->group();
const Instrument* instrument = staff->part()->instr();
int startTrack = staffIdx * VOICES;
int endTrack = startTrack + VOICES;

AccidentalState as; // list of already set accidentals for this measure
AccidentalState as; // state of already set accidentals for this measure
Staff* staff = score()->staff(staffIdx);
as.init(staff->keymap()->key(tick()));

for (Segment* segment = first(Segment::SegChordRest); segment; segment = segment->next(Segment::SegChordRest)) {
int startTrack = staffIdx * VOICES;
int endTrack = startTrack + VOICES;

for (Segment* s = first(Segment::SegChordRest); s; s = s->next(Segment::SegChordRest)) {
for (int track = startTrack; track < endTrack; ++track) {
Chord* chord = static_cast<Chord*>(segment->element(track));
Chord* chord = static_cast<Chord*>(s->element(track));
if (!chord || chord->type() != CHORD)
continue;
chord->updateNotes(&as);
}
}
}

// TAB_STAFF is different, as each note has to be fretted
// in the context of the all of the chords of the whole segment

if (staffGroup == TAB_STAFF_GROUP) {
for (Chord* ch : chord->graceNotes())
instrument->stringData()->fretChords(ch);
instrument->stringData()->fretChords(chord);
continue; // skip other staff type cases
}

// PITCHED_ and PERCUSSION_STAFF can go note by note
//---------------------------------------------------------
// cmdUpdateNotes
/// recompute note lines and accidental
/// undoable add/remove
//---------------------------------------------------------

void Measure::cmdUpdateNotes(int staffIdx)
{
AccidentalState as; // list of already set accidentals for this measure
Staff* staff = score()->staff(staffIdx);
as.init(staff->keymap()->key(tick()));

for (Chord* ch : chord->graceNotes()) {
QList<Note*> notes(ch->notes()); // we need a copy!
for (Note* note : notes)
note->updateAccidental(&as);
ch->sortNotes();
}
int startTrack = staffIdx * VOICES;
int endTrack = startTrack + VOICES;

QList<Note*> notes(chord->notes()); // we need a copy!
for (Note* note : notes) {
switch(staffGroup) {
case STANDARD_STAFF_GROUP:
if (note->tieBack()) {
if (note->accidental() && note->tpc() == note->tieBack()->startNote()->tpc()) {
// TODO: remove accidental only if note is not
// on new system
score()->undoRemoveElement(note->accidental());
}
}
note->updateAccidental(&as);
break;
case PERCUSSION_STAFF_GROUP:
{
Drumset* drumset = instrument->drumset();
int pitch = note->pitch();
if (drumset) {
if (!drumset->isValid(pitch)) {
// qDebug("unmapped drum note %d", pitch);
}
else {
note->setHeadGroup(drumset->noteHead(pitch));
note->setLine(drumset->line(pitch));
continue;
}
}
}
break;
case TAB_STAFF_GROUP: // to avoid compiler warning
break;
}
}
chord->sortNotes();
for (Segment* segment = first(Segment::SegChordRest); segment; segment = segment->next(Segment::SegChordRest)) {
for (int track = startTrack; track < endTrack; ++track) {
Chord* chord = static_cast<Chord*>(segment->element(track));
if (!chord || chord->type() != CHORD)
continue;
chord->cmdUpdateNotes(&as);
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions libmscore/measure.h
Original file line number Diff line number Diff line change
Expand Up @@ -278,9 +278,9 @@ class Measure : public MeasureBase {
bool isEmpty() const;
bool isOnlyRests(int track) const;

// void layoutChords0(Segment* segment, int startTrack);
void layout10(int staffIdx);
void updateAccidentals(int staffIdx);
void updateNotes(int staffIdx);
void cmdUpdateNotes(int staffIdx);

void layoutStage1();
int playbackCount() const { return _playbackCount; }
void setPlaybackCount(int val) { _playbackCount = val; }
Expand Down
Loading

0 comments on commit 5fb4076

Please sign in to comment.