    //=============================================================================
    //  MuseScore
    //  Music Composition & Notation
    //
    //  Copyright (C) 2002-2017 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 "musescore.h"
    #include "scoreview.h"
    #include "texttools.h"
    #include "libmscore/chordrest.h"
    #include "libmscore/harmony.h"
    #include "libmscore/score.h"
    #include "libmscore/segment.h"
    #include "libmscore/measure.h"

    namespace Ms {

    //---------------------------------------------------------
    //   harmonyTab
    //---------------------------------------------------------

    void ScoreView::harmonyTab(bool back)
          {
          Harmony* harmony = toHarmony(editData.element);
          if (!harmony->parent() || harmony->parent()->type() != ElementType::SEGMENT){
                qDebug("harmonyTab: no segment parent");
                return;
                }
          int track        = harmony->track();
          Segment* segment = static_cast<Segment*>(harmony->parent());
          if (!segment) {
                qDebug("harmonyTicksTab: no segment");
                return;
                }

          // moving to next/prev measure

          Measure* measure = segment->measure();
          if (measure) {
                if (back)
                      measure = measure->prevMeasure();
                else
                      measure = measure->nextMeasure();
                }
          if (!measure) {
                qDebug("harmonyTab: no prev/next measure");
                return;
                }

          segment = measure->findSegment(SegmentType::ChordRest, measure->tick());
          if (!segment) {
                qDebug("harmonyTab: no ChordRest segment as measure");
                return;
                }

          changeState(ViewState::NORMAL);

          _score->startCmd();

          // search for next chord name
          harmony = 0;
          foreach(Element* e, segment->annotations()) {
                if (e->isHarmony() && e->track() == track) {
                      Harmony* h = toHarmony(e);
                      harmony = h;
                      break;
                      }
                }

          if (!harmony) {
                harmony = new Harmony(_score);
                harmony->setTrack(track);
                harmony->setParent(segment);
                _score->undoAddElement(harmony);
                }

          _score->select(harmony, SelectType::SINGLE, 0);
          startEdit(harmony, Grip::NO_GRIP);
    //      mscore->changeState(mscoreState());

          adjustCanvasPosition(harmony, false);
    //TODO-edit      toHarmony(editData.element)->moveCursorToEnd();
          _score->update();
          }

    //---------------------------------------------------------
    //   harmonyBeatsTab
    //    manages [;:], moving forward or back to the next beat
    //    and Space/Shift-Space, to stop at next note, rest, harmony or beat.
    //---------------------------------------------------------

    void ScoreView::harmonyBeatsTab(bool noterest, bool back)
          {
          Harmony* harmony = toHarmony(editData.element);
          int track        = harmony->track();
          Segment* segment = toSegment(harmony->parent());
          if (!segment) {
                qDebug("harmonyBeatsTab: no segment");
                return;
                }
          Measure* measure = segment->measure();
          int tick = segment->tick();

          if (back && tick == measure->tick()) {
                // previous bar, if any
                measure = measure->prevMeasure();
                if (!measure) {
                      qDebug("harmonyBeatsTab: no previous measure");
                      return;
                      }
                }

          Fraction f = measure->len();
          int ticksPerBeat = f.ticks() / ((f.numerator()>3 && (f.numerator()%3)==0 && f.denominator()>4) ? f.numerator()/3 : f.numerator());
          int tickInBar = tick - measure->tick();
          int newTick   = measure->tick() + ((tickInBar + (back?-1:ticksPerBeat)) / ticksPerBeat) * ticksPerBeat;

          // look for next/prev beat, note, rest or chord
          for (;;) {
                segment = back ? segment->prev1(SegmentType::ChordRest) : segment->next1(SegmentType::ChordRest);

                if (!segment || (back ? (segment->tick() < newTick) : (segment->tick() > newTick))) {
                      // no segment or moved past the beat - create new segment
                      if (!back && newTick >= measure->tick() + f.ticks()) {
                            // next bar, if any
                            measure = measure->nextMeasure();
                            if (!measure) {
                                  qDebug("harmonyBeatsTab: no next measure");
                                  return;
                                  }
                            }
                      segment = new Segment(measure, SegmentType::ChordRest, newTick - measure->tick());
                      if (!segment) {
                            qDebug("harmonyBeatsTab: no prev segment");
                            return;
                            }
                      _score->undoAddElement(segment);
                      break;
                      }

                if (segment->tick() == newTick)
                      break;

                if (noterest) {
                      int minTrack = (track / VOICES ) * VOICES;
                      int maxTrack = minTrack + (VOICES-1);
                      if (segment->findAnnotationOrElement(ElementType::HARMONY, minTrack, maxTrack))
                            break;
                      }
                }

          changeState(ViewState::NORMAL);

          _score->startCmd();

          // search for next chord name
          harmony = 0;
          foreach (Element* e, segment->annotations()) {
                if (e->isHarmony() && e->track() == track) {
                      Harmony* h = toHarmony(e);
                      harmony = h;
                      break;
                      }
                }

          if (!harmony) {
                harmony = new Harmony(_score);
                harmony->setTrack(track);
                harmony->setParent(segment);
                _score->undoAddElement(harmony);
                }

          _score->select(harmony, SelectType::SINGLE, 0);
          startEdit(harmony, Grip::NO_GRIP);
          mscore->changeState(mscoreState());

          adjustCanvasPosition(harmony, false);
    //TODO-edit      toHarmony(editData.element)->moveCursorToEnd();
          _score->update();
          }

    //---------------------------------------------------------
    //   harmonyTicksTab
    //    manages [Ctrl] [1]-[9], moving forward the given number of ticks
    //---------------------------------------------------------

    void ScoreView::harmonyTicksTab(int ticks)
          {
          Harmony* harmony = static_cast<Harmony*>(editData.element);
          int track         = harmony->track();
          Segment* segment = static_cast<Segment*>(harmony->parent());
          if (!segment) {
                qDebug("harmonyTicksTab: no segment");
                return;
                }
          Measure* measure = segment->measure();

          int newTick   = segment->tick() + ticks;

          // find the measure containing the target tick
          while (newTick >= measure->tick() + measure->ticks()) {
                measure = measure->nextMeasure();
                if (!measure) {
                      qDebug("harmonyTicksTab: no next measure");
                      return;
                      }
                }

          // look for a segment at this tick; if none, create one
          while (segment && segment->tick() < newTick)
                segment = segment->next1(SegmentType::ChordRest);
          if (!segment || segment->tick() > newTick) {      // no ChordRest segment at this tick
                segment = new Segment(measure, SegmentType::ChordRest, newTick - measure->tick());
                if (!segment) {
                      qDebug("harmonyTicksTab: no next segment");
                      return;
                      }
                _score->undoAddElement(segment);
                }

          changeState(ViewState::NORMAL);

          _score->startCmd();

          // search for next chord name
          harmony = 0;
          foreach(Element* e, segment->annotations()) {
                if (e->type() == ElementType::HARMONY && e->track() == track) {
                      Harmony* h = static_cast<Harmony*>(e);
                      harmony = h;
                      break;
                      }
                }

          if (!harmony) {
                harmony = new Harmony(_score);
                harmony->setTrack(track);
                harmony->setParent(segment);
                _score->undoAddElement(harmony);
                }

          _score->select(harmony, SelectType::SINGLE, 0);
          startEdit(harmony, Grip::NO_GRIP);
          mscore->changeState(mscoreState());

          adjustCanvasPosition(harmony, false);
    //TODO-edit      ((Harmony*)editData.element)->moveCursorToEnd();
          _score->update();
          }

    //---------------------------------------------------------
    //   harmonyEndEdit
    //---------------------------------------------------------

    void ScoreView::harmonyEndEdit()
          {
          Harmony* harmony = static_cast<Harmony*>(editData.element);

          if (harmony->empty())
                _score->undoRemoveElement(harmony);
          }

    }

↑ V668 There is no sense in testing the 'segment' pointer against null, as the memory was allocated using the 'new' operator. The exception will be generated in the case of memory allocation error.

↑ V668 There is no sense in testing the 'segment' pointer against null, as the memory was allocated using the 'new' operator. The exception will be generated in the case of memory allocation error.