    //=============================================================================
    //  MuseScore
    //  Music Composition & Notation
    //
    //  Copyright (C) 2002-2016 Werner Schweer
    //
    //  This program is free software; you can redistribute it and/or modify
    //  it under the terms of the GNU General Public License version 2
    //  as published by the Free Software Foundation and appearing in
    //  the file LICENCE.GPL
    //=============================================================================

    #include "utils.h"
    #include "score.h"
    #include "chord.h"
    #include "measure.h"
    #include "tie.h"
    #include "tuplet.h"
    #include "staff.h"
    #include "part.h"
    #include "drumset.h"
    #include "slur.h"
    #include "navigate.h"
    #include "stringdata.h"
    #include "undo.h"
    #include "range.h"
    #include "excerpt.h"

    namespace Ms {

    //---------------------------------------------------------
    //   noteValForPosition
    //---------------------------------------------------------

    NoteVal Score::noteValForPosition(Position pos, bool &error)
          {
          error           = false;
          Segment* s      = pos.segment;
          int line        = pos.line;
          int tick        = s->tick();
          int staffIdx    = pos.staffIdx;
          Staff* st       = staff(staffIdx);
          ClefType clef   = st->clef(tick);
          const Instrument* instr = st->part()->instrument(s->tick());
          NoteVal nval;
          const StringData* stringData = 0;

          switch (st->staffType(tick)->group()) {
                case StaffGroup::PERCUSSION: {
                      if (_is.rest())
                            break;
                      const Drumset* ds = instr->drumset();
                      nval.pitch        = _is.drumNote();
                      if (nval.pitch < 0) {
                            error = true;
                            return nval;
                            }
                      nval.headGroup = ds->noteHead(nval.pitch);
                      if (nval.headGroup == NoteHead::Group::HEAD_INVALID) {
                            error = true;
                            return nval;
                            }
                      break;
                      }
                case StaffGroup::TAB: {
                      if (_is.rest()) {
                            error = true;
                            return nval;
                            }
                      stringData = instr->stringData();
                      if (line < 0 || line >= stringData->strings()) {
                            error = true;
                            return nval;
                            }
                      // build a default NoteVal for that string
                      nval.string = line;
                      if (pos.fret != FRET_NONE)          // if a fret is given, use it
                            nval.fret = pos.fret;
                      else {                              // if no fret, use 0 as default
                            _is.setString(line);
                            nval.fret = 0;
                            }
                      // reduce within fret limit
                      if (nval.fret > stringData->frets())
                            nval.fret = stringData->frets();
                      // for open strings, only accepts fret 0 (strings in StringData are from bottom to top)
                      int   strgDataIdx = stringData->strings() - line - 1;
                      if (nval.fret > 0 && stringData->stringList().at(strgDataIdx).open == true)
                            nval.fret = 0;
                      nval.pitch = stringData->getPitch(line, nval.fret, st, tick);
                      break;
                      }

                case StaffGroup::STANDARD: {
                      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);
                      if (styleB(StyleIdx::concertPitch))
                            nval.tpc1 = step2tpc(step % 7, acci);
                      else {
                            nval.pitch += instr->transpose().chromatic;
                            nval.tpc2 = step2tpc(step % 7, acci);
                            Interval v = st->part()->instrument(tick)->transpose();
                            if (v.isZero())
                                  nval.tpc1 = nval.tpc2;
                            else
                                  nval.tpc1 = Ms::transposeTpc(nval.tpc2, v, true);
                            }
                      }
                      break;
                }
          return nval;
          }

    //---------------------------------------------------------
    //   addPitch
    //---------------------------------------------------------

    Note* Score::addPitch(NoteVal& nval, bool addFlag)
          {
          if (addFlag) {
                Chord* c = toChord(_is.lastSegment()->element(_is.track()));

                if (c == 0 || !c->isChord()) {
                      qDebug("Score::addPitch: cr %s", c ? c->name() : "zero");
                      return 0;
                      }
                Note* note = addNote(c, nval);
                if (_is.lastSegment() == _is.segment()) {
                      NoteEntryMethod entryMethod = _is.noteEntryMethod();
                      if (entryMethod != NoteEntryMethod::REALTIME_AUTO && entryMethod != NoteEntryMethod::REALTIME_MANUAL)
                            _is.moveToNextInputPos();
                      }
                return note;
                }
          expandVoice();

          // insert note
          Direction stemDirection = Direction::AUTO;
          int track               = _is.track();
          if (_is.drumNote() != -1) {
                nval.pitch        = _is.drumNote();
                const Drumset* ds = _is.drumset();
                nval.headGroup    = ds->noteHead(nval.pitch);
                stemDirection     = ds->stemDirection(nval.pitch);
                track             = ds->voice(nval.pitch) + (_is.track() / VOICES) * VOICES;
                _is.setTrack(track);
                expandVoice();
                }
          if (!_is.cr())
                return 0;
          Fraction duration;
          if (_is.usingNoteEntryMethod(NoteEntryMethod::REPITCH)) {
                duration = _is.cr()->duration();
                }
          else {
                duration = _is.duration().fraction();
                }
          Note* note = 0;
          Note* firstTiedNote = 0;
          Note* lastTiedNote = 0;
          if (_is.usingNoteEntryMethod(NoteEntryMethod::REPITCH) && _is.cr()->isChord()) {
                // repitch mode for MIDI input (where we are given a pitch) is handled here
                // for keyboard input (where we are given a staff position), there is a separate function Score::repitchNote()
                // the code is similar enough that it could possibly be refactored
                Chord* chord = toChord(_is.cr());
                note = new Note(this);
                note->setParent(chord);
                note->setTrack(chord->track());
                note->setNval(nval);
                lastTiedNote = note;
                if (!addFlag) {
                      std::vector<Note*> notes = chord->notes();
                      // break all ties into current chord
                      // these will exist only if user explicitly moved cursor to a tied-into note
                      // in ordinary use, cursor will autoamtically skip past these during note entry
                      for (Note* n : notes) {
                            if (n->tieBack())
                                  undoRemoveElement(n->tieBack());
                            }
                      // for single note chords only, preserve ties by changing pitch of all forward notes
                      // the tie forward itself will be added later
                      // multi-note chords get reduced to single note chords anyhow since we remove the old notes below
                      // so there will be no way to preserve those ties
                      if (notes.size() == 1 && notes.front()->tieFor()) {
                            Note* tn = notes.front()->tieFor()->endNote();
                            while (tn) {
                                  Chord* tc = tn->chord();
                                  if (tc->notes().size() != 1) {
                                        undoRemoveElement(tn->tieBack());
                                        break;
                                        }
                                  if (!firstTiedNote)
                                        firstTiedNote = tn;
                                  lastTiedNote = tn;
                                  undoChangePitch(tn, note->pitch(), note->tpc1(), note->tpc2());
                                  if (tn->tieFor())
                                        tn = tn->tieFor()->endNote();
                                  else
                                        break;
                                  }
                            }
                      // remove all notes from chord
                      // the new note will be added below
                      while (!chord->notes().empty())
                            undoRemoveElement(chord->notes().front());
                      }
                // add new note to chord
                undoAddElement(note);
                setPlayNote(true);
                // recreate tie forward if there is a note to tie to
                // one-sided ties will not be recreated
                if (firstTiedNote) {
                      Tie* tie = new Tie(this);
                      tie->setStartNote(note);
                      tie->setEndNote(firstTiedNote);
                      tie->setTrack(note->track());
                      undoAddElement(tie);
                      }
                select(lastTiedNote);
                }
          else if (!_is.usingNoteEntryMethod(NoteEntryMethod::REPITCH)) {
                Segment* seg = setNoteRest(_is.segment(), track, nval, duration, stemDirection);
                if (seg) {
                      note = toChord(seg->element(track))->upNote();
                      }
                }

          if (_is.slur()) {
                //
                // extend slur
                //
                ChordRest* e = searchNote(_is.tick(), _is.track());
                if (e) {
                      int stick = 0;
                      Element* ee = _is.slur()->startElement();
                      if (ee->isChordRest())
                            stick = toChordRest(ee)->tick();
                      else if (ee->isNote())
                            stick = toNote(ee)->chord()->tick();
                      if (stick == e->tick()) {
                            _is.slur()->setTick(stick);
                            _is.slur()->setStartElement(e);
                            }
                      else {
                            _is.slur()->setTick2(e->tick());
                            _is.slur()->setEndElement(e);
                            }
                      }
                else
                      qDebug("addPitch: cannot find slur note");
                }
          if (_is.usingNoteEntryMethod(NoteEntryMethod::REPITCH)) {
                // move cursor to next note, but skip tied notes (they were already repitched above)
                ChordRest* next = lastTiedNote ? nextChordRest(lastTiedNote->chord()) : nextChordRest(_is.cr());
                while (next && !next->isChord())
                      next = nextChordRest(next);
                if (next)
                      _is.moveInputPos(next->segment());
                }
          else {
                NoteEntryMethod entryMethod = _is.noteEntryMethod();
                if (entryMethod != NoteEntryMethod::REALTIME_AUTO && entryMethod != NoteEntryMethod::REALTIME_MANUAL)
                      _is.moveToNextInputPos();
                }
          return note;
          }

    //---------------------------------------------------------
    //   putNote
    //    mouse click in state NoteType::ENTRY
    //---------------------------------------------------------

    void Score::putNote(const QPointF& pos, bool replace, bool insert)
          {
          Position p;
          if (!getPosition(&p, pos, _is.voice())) {
                qDebug("cannot put note here, get position failed");
                return;
                }
          Score* score = p.segment->score();
          if (score->inputState().usingNoteEntryMethod(NoteEntryMethod::REPITCH))
                score->repitchNote(p, replace);
          else {
                if (insert)
                      score->insertChord(p);
                else
                      score->putNote(p, replace);
                }
          }

    void Score::putNote(const Position& p, bool replace)
          {
          Staff* st   = staff(p.staffIdx);
          Segment* s  = p.segment;

          _is.setTrack(p.staffIdx * VOICES + _is.voice());
          _is.setSegment(s);

          if (score()->excerpt() && !score()->excerpt()->tracks().isEmpty() && score()->excerpt()->tracks().key(_is.track(), -1) == -1)
                return;

          Direction stemDirection = Direction::AUTO;
          bool error;
          NoteVal nval = noteValForPosition(p, error);
          if (error)
                return;

          const StringData* stringData = 0;
          switch (st->staffType(s->tick())->group()) {
                case StaffGroup::PERCUSSION: {
                      const Drumset* ds = st->part()->instrument(s->tick())->drumset();
                      stemDirection     = ds->stemDirection(nval.pitch);
                      break;
                      }
                case StaffGroup::TAB:
                      stringData = st->part()->instrument(s->tick())->stringData();
                      _is.setDrumNote(-1);
                      break;
                case StaffGroup::STANDARD:
                      _is.setDrumNote(-1);
                      break;
                }

          expandVoice();
          ChordRest* cr = _is.cr();
          bool addToChord = false;

          if (cr) {
                // retrieve total duration of current chord
                TDuration d = cr->durationType();
                // if not in replace mode AND chord duration == input duration AND not rest input
                // we need to add to current chord (otherwise, we will need to replace it or create a new one)
                if (!replace
                   && (d == _is.duration())
                   && cr->isChord()
                   && !_is.rest())
                      {
                      if (st->isTabStaff(cr->tick())) {      // TAB
                            // if a note on same string already exists, update to new pitch/fret
                            foreach (Note* note, toChord(cr)->notes())
                                  if (note->string() == nval.string) {       // if string is the same
                                        // if adding a new digit will keep fret number within fret limit,
                                        // add a digit to existing fret number
                                        if (stringData) {
                                              int fret = note->fret() * 10 + nval.fret;
                                              if (fret <= stringData->frets() ) {
                                                    nval.fret = fret;
                                                    nval.pitch = stringData->getPitch(nval.string, nval.fret, st, s->tick());
                                                    }
                                              else
                                                    qDebug("can't increase fret to %d", fret);
                                              }
                                        // set fret number (original or combined) in all linked notes
                                        int tpc1 = note->tpc1default(nval.pitch);
                                        int tpc2 = note->tpc2default(nval.pitch);
                                        undoChangeFretting(note, nval.pitch, nval.string, nval.fret, tpc1, tpc2);
                                        return;
                                        }
                            }
                      else {                        // not TAB
                            // if a note with the same pitch already exists in the chord, remove it
                            Chord* chord = toChord(cr);
                            Note* note = chord->findNote(nval.pitch);
                            if (note) {
                                  if (chord->notes().size() > 1)
                                        undoRemoveElement(note);
                                  return;
                                  }
                            }
                      addToChord = true;            // if no special case, add note to chord
                      }
                }
          if (addToChord && cr->isChord()) {
                // if adding, add!
                addNote(toChord(cr), nval);
                return;
                }
          else {
                // if not adding, replace current chord (or create a new one)

                if (_is.rest())
                      nval.pitch = -1;
                setNoteRest(_is.segment(), _is.track(), nval, _is.duration().fraction(), stemDirection);
                }
          if (!st->isTabStaff(cr->tick()))
                _is.moveToNextInputPos();
          }

    //---------------------------------------------------------
    //   repitchNote
    //---------------------------------------------------------

    void Score::repitchNote(const Position& p, bool replace)
          {
          Segment* s      = p.segment;
          int tick        = s->tick();
          Staff* st       = staff(p.staffIdx);
          ClefType clef   = st->clef(tick);

          NoteVal nval;
          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);

          if (styleB(StyleIdx::concertPitch))
                nval.tpc1 = step2tpc(step % 7, acci);
          else {
                nval.pitch += st->part()->instrument(s->tick())->transpose().chromatic;
                nval.tpc2 = step2tpc(step % 7, acci);
                }

          if (!_is.segment())
                return;

          Chord* chord;
          ChordRest* cr = _is.cr();
          if (!cr) {
                cr = _is.segment()->nextChordRest(_is.track());
                if (!cr)
                      return;
                }
          if (cr->isRest()) { //skip rests
                ChordRest* next = nextChordRest(cr);
                while(next && !next->isChord())
                      next = nextChordRest(next);
                if (next)
                      _is.moveInputPos(next->segment());
                return;
                }
          else {
                chord = toChord(cr);
                }
          Note* note = new Note(this);
          note->setParent(chord);
          note->setTrack(chord->track());
          note->setNval(nval);

          Note* firstTiedNote = 0;
          Note* lastTiedNote = note;
          if (replace) {
                std::vector<Note*> notes = chord->notes();
                // break all ties into current chord
                // these will exist only if user explicitly moved cursor to a tied-into note
                // in ordinary use, cursor will autoamtically skip past these during note entry
                for (Note* n : notes) {
                      if (n->tieBack())
                            undoRemoveElement(n->tieBack());
                      }
                // for single note chords only, preserve ties by changing pitch of all forward notes
                // the tie forward itself will be added later
                // multi-note chords get reduced to single note chords anyhow since we remove the old notes below
                // so there will be no way to preserve those ties
                if (notes.size() == 1 && notes.front()->tieFor()) {
                      Note* tn = notes.front()->tieFor()->endNote();
                      while (tn) {
                            Chord* tc = tn->chord();
                            if (tc->notes().size() != 1) {
                                  undoRemoveElement(tn->tieBack());
                                  break;
                                  }
                            if (!firstTiedNote)
                                  firstTiedNote = tn;
                            lastTiedNote = tn;
                            undoChangePitch(tn, note->pitch(), note->tpc1(), note->tpc2());
                            if (tn->tieFor())
                                  tn = tn->tieFor()->endNote();
                            else
                                  break;
                            }
                      }
                // remove all notes from chord
                // the new note will be added below
                while (!chord->notes().empty())
                      undoRemoveElement(chord->notes().front());
                }
          // add new note to chord
          undoAddElement(note);
          setPlayNote(true);
          setPlayChord(true);
          // recreate tie forward if there is a note to tie to
          // one-sided ties will not be recreated
          if (firstTiedNote) {
                Tie* tie = new Tie(this);
                tie->setStartNote(note);
                tie->setEndNote(firstTiedNote);
                tie->setTrack(note->track());
                undoAddElement(tie);
                }
          select(lastTiedNote);
          // move to next Chord
          ChordRest* next = nextChordRest(lastTiedNote->chord());
          while (next && !next->isChord())
                next = nextChordRest(next);
          if (next)
                _is.moveInputPos(next->segment());
          }

    //---------------------------------------------------------
    //   insertChord
    //---------------------------------------------------------

    void Score::insertChord(const Position& pos)
          {
          // insert
          // TODO:
          //    - check voices
          //    - split chord/rest

          Element* el = selection().element();
          if (!el || !(el->isNote() || el->isRest()))
                return;
          Segment* seg = pos.segment;
          if (seg->splitsTuplet()) {
                MScore::setError(CANNOT_INSERT_TUPLET);
                return;
                }
          if (_is.insertMode())
                globalInsertChord(pos);
          else
                localInsertChord(pos);
          }

    //---------------------------------------------------------
    //   localInsertChord
    //---------------------------------------------------------

    void Score::localInsertChord(const Position& pos)
          {
          TDuration duration = _is.duration();
          Fraction fraction  = duration.fraction();
          int len            = fraction.ticks();
          Segment* seg       = pos.segment;
          int tick           = seg->tick();
          Measure* m         = seg->measure();

          undoInsertTime(tick, len);
          undo(new InsertTime(this, tick, len));

          for (Segment* s = pos.segment; s; s = s-> next())
                s->undoChangeProperty(P_ID::TICK, s->rtick() + len);
          undo(new ChangeMeasureLen(m, m->len() + fraction));

          Segment* s = m->undoGetSegment(SegmentType::ChordRest, tick);
          Position p(pos);
          p.segment = s;

          int trackI = p.staffIdx * VOICES + _is.voice();
          for (int track = 0; track < _staves.size() * VOICES; ++track) {
                if (track == trackI)
                      putNote(p, true);
                else {
                      Segment* fs = m->first(SegmentType::ChordRest);
                      if (fs->tick() == tick && m->hasVoice(track)) {
                            setRest(fs->tick(),  track, fraction, false, nullptr, false);
                            continue;
                            }
                      Segment* seg1 = 0;
                      for (Segment* s = fs; s; s = s->next(SegmentType::ChordRest)) {
                            if (s->element(track)) {
                                  ChordRest* cr = toChordRest(s->element(track));
                                  if (s->tick() > tick)
                                        break;
                                  if (s->tick() + cr->duration().ticks() < tick)
                                        continue;
                                  seg1 = s;
                                  break;
                                  }
                            }
                      if (seg1) {
                            ChordRest* cr = toChordRest(seg1->element(track));
                            if (seg1->tick() + cr->duration().ticks() == tick) {
                                  addRest(s, track, duration, nullptr);
                                  }
                            else if (cr->isFullMeasureRest()) {
                                  // do nothing
                                  }
                            else
                                  changeCRlen(cr, fraction + cr->duration());
                            }
                      }
                }
          }

    //---------------------------------------------------------
    //   globalInsertChord
    //---------------------------------------------------------

    void Score::globalInsertChord(const Position& pos)
          {
          ChordRest* cr = selection().cr();
          int track = cr ? cr->track() : -1;
          deselectAll();
          Segment* s1        = pos.segment;
          Segment* s2        = lastSegment();
          TDuration duration = _is.duration();
          Fraction fraction  = duration.fraction();
          ScoreRange r;

          r.read(s1, s2, false);

          int strack = 0;                      // for now for all tracks
          int etrack = nstaves() * VOICES;
          int stick  = s1->tick();
          int etick  = s2->tick();
          int ticks  = fraction.ticks();

          Fraction len = r.duration();
          if (!r.truncate(fraction))
                appendMeasures(1);

          putNote(pos, true);
          int dtick = s1->tick() + ticks;
          int voiceOffsets[VOICES] { 0, 0, 0, 0 };
          len = r.duration();
          for (int staffIdx = 0; staffIdx < nstaves(); ++staffIdx)
                makeGap1(dtick, staffIdx, r.duration(), voiceOffsets);
          r.write(this, dtick);

          for (auto i :  spanner()) {
                Spanner* s = i.second;
                if (s->track() >= strack && s->track() < etrack) {
                      if (s->tick() >= stick && s->tick() < etick)
                            s->undoChangeProperty(P_ID::SPANNER_TICK, s->tick() + ticks);
                      else if (s->tick2() >= stick && s->tick2() < etick)
                            s->undoChangeProperty(P_ID::SPANNER_TICKS, s->ticks() + ticks);
                      }
                }

          if (track != -1) {
                Measure* m = tick2measure(dtick);
                Segment* s = m->findSegment(SegmentType::ChordRest, dtick);
                Element* e = s->element(track);
                if (e)
                      select(e->isChord() ? toChord(e)->notes().front() : e);
                }
          }

    } // namespace Ms

↑ V547 Expression '!addFlag' is always true.