Пример #1
0
void TestMeasure::checkMeasure()
      {
      MasterScore* score = readScore(DIR + "checkMeasure.mscx");
      Element* tst       = 0;
      Measure* m         = score->firstMeasure()->nextMeasure();

      Segment* s = m->undoGetSegment(Segment::Type::ChordRest, 2880);
      tst = s->element(1);
      Q_ASSERT(tst);

      QVERIFY(tst->isRest() && toRest(tst)->isGap() && toRest(tst)->actualTicks() == 480/*&& toRest(tst)->durationType() == TDuration::DurationType::V_HALF*/);

      m = m->nextMeasure();
//      s = m->undoGetSegment(Segment::Type::ChordRest, 3840);
//      tst = s->element(2);
//      Q_ASSERT(tst);

//      QVERIFY(tst->isRest() && toRest(tst)->isGap() && toRest(tst)->actualTicks() == 480/*&& toRest(tst)->durationType() == TDuration::DurationType::V_HALF*/);

      m = m->nextMeasure();
      s = m->undoGetSegment(Segment::Type::ChordRest, 6240);
      tst = s->element(1);
      Q_ASSERT(tst);

      QVERIFY(tst->isRest() && toRest(tst)->isGap() && toRest(tst)->actualTicks() == 120/*&& toRest(tst)->durationType() == TDuration::DurationType::V_HALF*/);

      s = m->undoGetSegment(Segment::Type::ChordRest, 6480);
      tst = s->element(1);
      Q_ASSERT(tst);

      QVERIFY(tst->isRest() && toRest(tst)->isGap() && toRest(tst)->actualTicks() == 120/*&& toRest(tst)->durationType() == TDuration::DurationType::V_HALF*/);

      delete score;
      }
Пример #2
0
Element* Clef::drop(const DropData& data)
      {
      Element* e = data.element;
      Clef* c = 0;
      if (e->isClef()) {
            Clef* clef = toClef(e);
            ClefType stype  = clef->clefType();
            if (clefType() != stype) {
                  score()->undoChangeClef(staff(), segment(), stype);
                  c = this;
                  }
            }
      else if (e->isAmbitus()) {
            /*if (!generated())*/ {
                  Measure*    meas  = measure();
                  Segment*    segm  = meas->getSegment(Segment::Type::Ambitus, meas->tick());
                  if (segm->element(track()))
                        score()->undoRemoveElement(segm->element(track()));
                  Ambitus* r = new Ambitus(score());
                  r->setParent(segm);
                  r->setTrack(track());
                  score()->undoAddElement(r);
                  }
            }
      delete e;
      return c;
      }
Пример #3
0
void TestBarline::barline04()
      {
      Score* score = readScore(DIR + "barline04.mscx");
      QVERIFY(score);
      score->doLayout();

      score->startCmd();
      // 'go' to 5th measure
      Measure* msr = score->firstMeasure();
      for (int i=0; i < 4; i++)
            msr = msr->nextMeasure();
      // check span data of measure-initial start-repeat bar line
      Segment* seg = msr->findSegment(SegmentType::StartRepeatBarLine, msr->tick());
      QVERIFY2(seg != nullptr, "No SegStartRepeatBarLine segment in measure 5.");

      BarLine* bar = static_cast<BarLine*>(seg->element(0));
      QVERIFY2(bar != nullptr, "No start-repeat barline in measure 5.");

      bar->undoChangeProperty(Pid::BARLINE_SPAN, 2);
      bar->undoChangeProperty(Pid::BARLINE_SPAN_FROM, 2);
      bar->undoChangeProperty(Pid::BARLINE_SPAN_TO, 6);
      score->endCmd();

      QVERIFY2(bar->spanStaff() && bar->spanFrom() == 2 && bar->spanTo() == 6,
            "Wrong span data in start-repeat barline of measure 5.");

      // check start-repeat bar ine in second staff is gone
      QVERIFY2(seg->element(1) == nullptr, "Extra start-repeat barline in 2nd staff of measure 5.");

//      QVERIFY(saveCompareScore(score, "barline04.mscx", DIR + "barline04-ref.mscx"));
      delete score;
      }
Пример #4
0
void Glissando::layout()
      {
      Chord* chord = static_cast<Chord*>(parent());
      if (chord == 0) {
            return;
            }
      Note* anchor2   = chord->upNote();
      Segment* s = chord->segment();
      s = s->prev1();
      while (s) {
            if ((s->subtype() & (Segment::SegChordRestGrace)) && s->element(track()))
                  break;
            s = s->prev1();
            }
      if (s == 0) {
            qDebug("no segment for first note of glissando found\n");
            return;
            }
      ChordRest* cr = static_cast<ChordRest*>(s->element(track()));
      if (cr == 0 || cr->type() != CHORD) {
            qDebug("no first note for glissando found, track %d\n", track());
            return;
            }
      Note* anchor1 = static_cast<Chord*>(cr)->upNote();

      setPos(0.0, 0.0);

      QPointF cp1    = anchor1->pagePos();
      QPointF cp2    = anchor2->pagePos();

      // construct line from notehead to notehead
      qreal x1 = (anchor1->headWidth()) - (cp2.x() - cp1.x());
      qreal y1 = anchor1->pos().y();
      qreal x2 = anchor2->pos().x();
      qreal y2 = anchor2->pos().y();

      // on TAB's, adjust lower end point from string line height to base of note height (= ca. half line spacing)
      if (chord->staff()->isTabStaff()) {
            qreal yOff = chord->staff()->lineDistance() * 0.5 * spatium();
            if (anchor1->pitch() > anchor2->pitch())  // descending glissando:
                  y2 += yOff;                               // move ending point to base of note
            else                                      // ascending glissando:
                  y1 += yOff;                               // move starting point to base of note
            }

      QLineF fullLine(x1, y1, x2, y2);

      // shorten line on each side by offsets
      qreal xo = spatium() * .5;
      qreal yo = xo;   // spatium() * .5;
      QPointF p1 = fullLine.pointAt(xo / fullLine.length());
      QPointF p2 = fullLine.pointAt(1 - (yo / fullLine.length()));

      line = QLineF(p1, p2);
      qreal lw = spatium() * .15 * .5;
      QRectF r = QRectF(line.p1(), line.p2()).normalized();
      setbbox(r.adjusted(-lw, -lw, lw, lw));
      }
Пример #5
0
void TestClefCourtesy::clef_courtesy02()
      {
      Score* score = readScore(DIR + "clef_courtesy02.mscx");
      score->doLayout();

      // 'go' to 4th measure
      Measure* m1 = score->firstMeasure();
      for (int i=0; i < 3; i++)
            m1 = m1->nextMeasure();
      // make a clef-drop object and drop it to the measure
      Clef* clef = new Clef(score); // create a new element, as Measure::drop() will eventually delete it
      clef->setClefType(ClefType::G1);
      DropData dropData;
      dropData.pos = m1->pagePos();
      dropData.element = clef;
      m1->drop(dropData);

      // 'go' to 7th measure
      Measure* m2 = m1;
      for (int i=0; i < 3; i++)
            m2 = m2->nextMeasure();
      // make a clef-drop object and drop it to the measure
      clef = new Clef(score); // create a new element, as Measure::drop() will eventually delete it
      clef->setClefType(ClefType::G);
      dropData.pos = m2->pagePos();
      dropData.element = clef;
      m2->drop(dropData);
      score->doLayout();

      // check both clef elements are there, but none is shown
      Clef*    clefCourt = nullptr;
      Measure* m = m1->prevMeasure();
      Segment* seg = m->findSegment(SegmentType::Clef, m1->tick());
      QVERIFY2(seg != nullptr, "No SegClef in measure 3.");
      clefCourt = static_cast<Clef*>(seg->element(0));
      QVERIFY2(clefCourt != nullptr, "No courtesy clef element in measure 3.");
      QVERIFY2(clefCourt->bbox().width() == 0, "Courtesy clef in measure 3 is NOT hidden.");

      clefCourt = nullptr;
      m = m2->prevMeasure();
      seg = m->findSegment(SegmentType::Clef, m2->tick());
      QVERIFY2(seg != nullptr, "No SegClef in measure 6.");
      clefCourt = static_cast<Clef*>(seg->element(0));
      QVERIFY2(clefCourt != nullptr, "No courtesy clef element in measure 6.");
      QVERIFY2(clefCourt->bbox().width() == 0, "Courtesy clef in measure 3 is NOT hidden.");

      QVERIFY(saveCompareScore(score, "clef_courtesy02.mscx", DIR + "clef_courtesy02-ref.mscx"));
      delete score;
      }
Пример #6
0
Segment* InputState::nextInputPos() const
      {
      Measure* m = _segment->measure();
      Segment* s = _segment->next1(Segment::Type::ChordRest);
      for (; s; s = s->next1(Segment::Type::ChordRest)) {
            if (s->element(_track) || s->measure() != m) {
                  if (s->element(_track)) {
                        if (s->element(_track)->isRest() && toRest(s->element(_track))->isGap())
                              continue;
                        }
                  return s;
                  }
            }
      return 0;
      }
Пример #7
0
void Glissando::layout()
      {
      Chord* chord = static_cast<Chord*>(parent());
      if (chord == 0) {
            return;
            }
      Note* anchor2   = chord->upNote();
      Segment* s = chord->segment();
      s = s->prev1();
      while (s) {
            if ((s->subtype() == SegChordRest || s->subtype() == SegGrace) && s->element(track()))
                  break;
            s = s->prev1();
            }
      if (s == 0) {
            qDebug("no segment for first note of glissando found\n");
            return;
            }
      ChordRest* cr = static_cast<ChordRest*>(s->element(track()));
      if (cr == 0 || cr->type() != CHORD) {
            qDebug("no first note for glissando found, track %d\n", track());
            return;
            }
      Note* anchor1 = static_cast<Chord*>(cr)->upNote();

      setPos(0.0, 0.0);

      QPointF cp1    = anchor1->pagePos();
      QPointF cp2    = anchor2->pagePos();

      // construct line from notehead to notehead
      qreal x1 = (anchor1->headWidth()) - (cp2.x() - cp1.x());
      qreal y1 = anchor1->pos().y();
      qreal x2 = anchor2->pos().x();
      qreal y2 = anchor2->pos().y();
      QLineF fullLine(x1, y1, x2, y2);

      // shorten line on each side by offsets
      qreal xo = spatium() * .5;
      qreal yo = xo;   // spatium() * .5;
      QPointF p1 = fullLine.pointAt(xo / fullLine.length());
      QPointF p2 = fullLine.pointAt(1 - (yo / fullLine.length()));

      line = QLineF(p1, p2);
      qreal lw = spatium() * .15 * .5;
      QRectF r = QRectF(line.p1(), line.p2()).normalized();
      setbbox(r.adjusted(-lw, -lw, lw, lw));
      }
Пример #8
0
Clef* Clef::otherClef()
      {
      // if not in a clef-segment-measure hierarchy, do nothing
      if (!parent() || !parent()->isSegment())
            return nullptr;
      Segment* segm = toSegment(parent());
      int segmTick = segm->tick();
      if (!segm->parent() || !segm->parent()->isMeasure())
            return nullptr;
      Measure* meas = toMeasure(segm->parent());
      Measure* otherMeas = nullptr;
      Segment* otherSegm = nullptr;
      if (segmTick == meas->tick())                         // if clef segm is measure-initial
            otherMeas = meas->prevMeasure();                // look for a previous measure
      else if (segmTick == meas->tick() + meas->ticks())    // if clef segm is measure-final
            otherMeas = meas->nextMeasure();                // look for a next measure
      if (!otherMeas)
            return nullptr;
      // look for a clef segment in the 'other' measure at the same tick of this clef segment
      otherSegm = otherMeas->findSegment(SegmentType::Clef | SegmentType::HeaderClef, segmTick);
      if (!otherSegm)
            return nullptr;
      // if any 'other' segment found, look for a clef in the same track as this
      return toClef(otherSegm->element(track()));
      }
Пример #9
0
void TestBarline::barline02()
      {
      char msg[256];
      Score* score = readScore(DIR + "barline02.mscx");
      QVERIFY(score);
      Measure* msr = score->firstMeasure()->nextMeasure();
      TimeSig* ts  = new TimeSig(score);
      ts->setSig(Fraction(3, 4), TimeSigType::NORMAL);

      score->cmdAddTimeSig(msr, 0, ts, false);
      score->doLayout();

      msr = score->firstMeasure();
      int msrNo = 1;
      while ((msr = msr->nextMeasure())) {
            ++msrNo;
            Segment* seg = msr->findSegment(SegmentType::EndBarLine, msr->tick()+msr->ticks());
            sprintf(msg, "No SegEndBarLine in measure %d.", msrNo);
            QVERIFY2(seg != nullptr, msg);

            BarLine* bar = static_cast<BarLine*>(seg->element(0));
            sprintf(msg, "No barline in measure %d.", msrNo);
            QVERIFY2(bar != nullptr, msg);

            // bar line should be generated if NORMAL, except the END one at the end
            sprintf(msg, "Barline in measure %d changed into 'non-generated'.", msrNo);
// ws: end barline is also generated
//            bool test = (bar->barLineType() == BarLineType::NORMAL) ? bar->generated() : !bar->generated();
            bool test = bar->generated();
            QVERIFY2(test, msg);
      }
//      QVERIFY(saveCompareScore(score, "barline02.mscx", DIR + "barline02-ref.mscx"));
      delete score;
      }
Пример #10
0
Note* Score::upAlt(Element* element)
      {
      Element* re = 0;
      if (element->type() == Element::REST) {
            if (_is.track() <= 0)
                  return 0;
            _is.setTrack(_is.track() - 1);
            re = searchNote(static_cast<Rest*>(element)->tick(), _is.track());
            }
      else if (element->type() == Element::NOTE) {
            // find segment
            Chord* chord     = static_cast<Note*>(element)->chord();
            Segment* segment = chord->segment();

            // collect all notes for this segment in noteList:
            QList<Note*> rnl;
            int tracks = nstaves() * VOICES;
            for (int track = 0; track < tracks; ++track) {
                  Element* el = segment->element(track);
                  if (!el || el->type() != Element::CHORD)
                        continue;
                  rnl.append(static_cast<Chord*>(el)->notes());
                  qSort(rnl.begin(), rnl.end(), noteLessThan);
                  int idx = rnl.indexOf(static_cast<Note*>(element));
                  if (idx < rnl.size()-1)
                        ++idx;
                  re = rnl.value(idx);
                  }
            }
      if (re == 0)
            return 0;
      if (re->type() == Element::CHORD)
            re = ((Chord*)re)->notes().front();
      return (Note*)re;
      }
bool haveTupletsEnoughElements(const Staff *staff)
      {
      const int strack = staff->idx() * VOICES;

      for (int voice = 0; voice < VOICES; ++voice) {
            for (Segment *seg = staff->score()->firstSegment(); seg; seg = seg->next1()) {
                  if (seg->segmentType() == Segment::Type::ChordRest) {
                        const ChordRest *cr = static_cast<ChordRest *>(seg->element(strack + voice));
                        if (!cr)
                              continue;
                        const Tuplet *tuplet = cr->tuplet();
                        if (tuplet) {
                              if (tuplet->elements().size() <= 1) {
                                    printInvalidTupletLocation(seg->measure()->no(), staff->idx());
                                    return false;
                                    }
                              int chordCount = 0;
                              for (const auto &e: tuplet->elements()) {
                                    const ChordRest *cr = static_cast<ChordRest *>(e);
                                    if (cr && cr->type() == Element::Type::CHORD)
                                          ++chordCount;
                                    }
                              if (chordCount == 0) {
                                    printInvalidTupletLocation(seg->measure()->no(), staff->idx());
                                    return false;
                                    }
                              }
                        }
                  }
            }
      return true;
      }
Пример #12
0
void Fermata::layout()
      {
      Segment* s = segment();
      setPos(QPointF());
      if (!s) {          // for use in palette
            setOffset(0.0, 0.0);
            QRectF b(symBbox(_symId));
            setbbox(b.translated(-0.5 * b.width(), 0.0));
            return;
            }

      if (isStyled(Pid::OFFSET))
            setOffset(propertyDefault(Pid::OFFSET).toPointF());
      Element* e = s->element(track());
      if (e) {
            if (e->isChord())
                  rxpos() += score()->noteHeadWidth() * staff()->mag(Fraction(0, 1)) * .5;
            else
                  rxpos() += e->x() + e->width() * staff()->mag(Fraction(0, 1)) * .5;
            }

      QString name = Sym::id2name(_symId);
      if (placeAbove()) {
            if (name.endsWith("Below"))
                  _symId = Sym::name2id(name.left(name.size() - 5) + "Above");
            }
      else {
            rypos() += staff()->height();
            if (name.endsWith("Above"))
                  _symId = Sym::name2id(name.left(name.size() - 5) + "Below");
            }
      QRectF b(symBbox(_symId));
      setbbox(b.translated(-0.5 * b.width(), 0.0));
      autoplaceSegmentElement(styleP(Sid::fermataMinDistance));
      }
Пример #13
0
ChordRest* Score::nextTrack(ChordRest* cr)
      {
      if (!cr)
            return 0;

      ChordRest* el = 0;
      Measure* measure = cr->measure();
      int track = cr->track();
      int tracks = nstaves() * VOICES;

      while (!el) {
            // find next non-empty track
            while (++track < tracks){
                  if (measure->hasVoice(track))
                        break;
                  }
            // no more tracks, return original element
            if (track == tracks)
                  return cr;
            // find element at same or previous segment within this track
            for (Segment* segment = cr->segment(); segment; segment = segment->prev(Segment::Type::ChordRest)) {
                  el = static_cast<ChordRest*>(segment->element(track));
                  if (el)
                        break;
                  }
            }
      return el;
      }
Пример #14
0
void Fermata::layout()
      {
      Segment* s = segment();
      if (!s) {          // for use in palette
            setPos(QPointF());
            return;
            }

      qreal x = 0.0;
      Element* e = s->element(track());
      if (e) {
            if (e->isChord())
                  x = score()->noteHeadWidth() * staff()->mag(0) * .5;
            else
                  x = e->x() + e->width() * staff()->mag(0) * .5;
            }
      qreal y = placeAbove() ? styleP(Sid::fermataPosAbove) : styleP(Sid::fermataPosBelow) + staff()->height();

      setPos(QPointF(x, y));

      // check used symbol

      QString name = Sym::id2name(_symId);
      if (placeAbove()) {
            if (name.endsWith("Below"))
                  _symId = Sym::name2id(name.left(name.size() - 5) + "Above");
            }
      else {
            if (name.endsWith("Above"))
                  _symId = Sym::name2id(name.left(name.size() - 5) + "Below");
            }
      QRectF b(symBbox(_symId));
      setbbox(b.translated(-0.5 * b.width(), 0.0));
      autoplaceSegmentElement(styleP(Sid::fermataMinDistance));
      }
Пример #15
0
void InspectorClef::setElement()
      {
      otherClef = nullptr;                      // no 'other clef' yet
      InspectorElementBase::setElement();

      // try to locate the 'other clef' of a courtesy / main pair
      Clef* clef = toClef(inspector->element());
      // if not in a clef-segment-measure hierarchy, do nothing
      if (!clef->parent() || clef->parent()->type() != ElementType::SEGMENT)
            return;
      Segment*    segm = toSegment(clef->parent());
      int         segmTick = segm->tick();
      if (!segm->parent() || segm->parent()->type() != ElementType::MEASURE)
            return;

      Measure* meas = toMeasure(segm->parent());
      Measure* otherMeas = nullptr;
      Segment* otherSegm = nullptr;
      if (segmTick == meas->tick())                         // if clef segm is measure-initial
            otherMeas = meas->prevMeasure();                // look for a previous measure
      else if (segmTick == meas->tick()+meas->ticks())      // if clef segm is measure-final
            otherMeas = meas->nextMeasure();                // look for a next measure
      // look for a clef segment in the 'other' measure at the same tick of this clef segment
      if (otherMeas)
            otherSegm = otherMeas->findSegment(SegmentType::Clef, segmTick);
      // if any 'other' segment found, look for a clef in the same track as this
      if (otherSegm)
            otherClef = toClef(otherSegm->element(clef->track()));
      }
Пример #16
0
void Dynamic::layout()
      {
      if (!readPos().isNull()) {
            if (score()->mscVersion() < 118) {
                  setReadPos(QPointF());
                  // hack: 1.2 boundingBoxes are a bit wider which results
                  // in symbols moved right
                  setUserXoffset(userOff().x() - spatium() * .6);
                  }
            }
      Text::layout();

      Segment* s = segment();
      for (int voice = 0; voice < VOICES; ++voice) {
            int t = (track() & ~0x3) + voice;
            Chord* c = static_cast<Chord*>(s->element(t));
            if (!c)
                  continue;
            if (c->type() == CHORD) {
                  qreal noteHeadWidth = score()->noteHeadWidth() * c->mag();
                  if (c->stem() && !c->up())  // stem down
                        rxpos() += noteHeadWidth * .25;  // center on stem + optical correction
                  else
                        rxpos() += noteHeadWidth * .5;   // center on note head
                  }
            else
                  rxpos() += c->width() * .5;
            break;
            }
      }
Пример #17
0
Note* searchTieNote114(Note* note)
      {
      Note* note2  = 0;
      Chord* chord = note->chord();
      Segment* seg = chord->segment();
      Part* part   = chord->staff()->part();
      int strack   = part->staves()->front()->idx() * VOICES;
      int etrack   = strack + part->staves()->size() * VOICES;

      while ((seg = seg->next1(Segment::SegChordRest))) {
            for (int track = strack; track < etrack; ++track) {
                  Chord* c = static_cast<Chord*>(seg->element(track));
                  if (c == 0 || (c->type() != Element::CHORD) || (c->track() != chord->track()))
                        continue;
                  int staffIdx = c->staffIdx() + c->staffMove();
                  if (staffIdx != chord->staffIdx() + chord->staffMove())  // cannot happen?
                        continue;
                  for (Note* n : c->notes()) {
                        if (n->pitch() == note->pitch()) {
                              if (note2 == 0 || c->track() == chord->track())
                                    note2 = n;
                              }
                        }
                  }
            if (note2)
                  break;
            }
      return note2;
      }
Пример #18
0
Segment* Score::tick2segmentEnd(int track, int tick) const
      {
      Measure* m = tick2measure(tick);
      if (m == 0) {
            qDebug("tick2segment(): not found tick %d\n", tick);
            return 0;
            }
      // loop over all segments
      for (Segment* segment = m->first(Segment::SegChordRest); segment; segment = segment->next(Segment::SegChordRest)) {
            ChordRest* cr = static_cast<ChordRest*>(segment->element(track));
            if (!cr)
                  continue;
            // TODO LVI: check if following is correct, see exceptions in
            // ExportMusicXml::chord() and ExportMusicXml::rest()
            int endTick = cr->tick() + cr->actualTicks();
            if (endTick < tick)
                  continue; // not found yet
            else if (endTick == tick) {
                  return segment; // found it
                  }
            else {
                  // endTick > tick (beyond the tick we are looking for)
                  return 0;
                  }
            }
      return 0;
      }
Пример #19
0
void ScoreView::lyricsReturn()
      {
      Lyrics* lyrics   = (Lyrics*)editObject;
      Segment* segment = lyrics->segment();

      endEdit();

      _score->startCmd();

      Lyrics* oldLyrics = lyrics;

      lyrics = static_cast<Lyrics*>(Element::create(lyrics->type(), _score));
      lyrics->setTrack(oldLyrics->track());
      lyrics->setParent(segment->element(oldLyrics->track()));
      lyrics->setNo(oldLyrics->no() + 1);
      _score->undoAddElement(lyrics);
      _score->select(lyrics, SELECT_SINGLE, 0);
      startEdit(lyrics, -1);
      mscore->changeState(mscoreState());

      adjustCanvasPosition(lyrics, false);
      _score->setLayoutAll(true);
      _score->end2();
      _score->end1();
      }
Пример #20
0
void detectSwing(Staff *staff, MidiOperation::Swing swingType)
      {
      Score *score = staff->score();
      const int strack = staff->idx() * VOICES;
      SwingDetector swingDetector(swingType);

      for (Segment *seg = score->firstSegment(Segment::SegChordRest); seg;
                                      seg = seg->next1(Segment::SegChordRest)) {
            for (int voice = 0; voice < VOICES; ++voice) {
                  ChordRest *cr = static_cast<ChordRest *>(seg->element(strack + voice));
                  if (!cr)
                        continue;
                  swingDetector.add(cr);
                  }
            }
      if (swingDetector.wasSwingApplied()) {
                        // add swing label to the score
            StaffText* st = new StaffText(score);
            st->setTextStyleType(TEXT_STYLE_STAFF);
            st->setText(swingCaption(swingType));
            Segment* seg = score->firstSegment(Segment::SegChordRest);
            st->setParent(seg);
            st->setTrack(strack);   // voice == 0
            score->addElement(st);
            }
      }
Пример #21
0
ChordRest* Score::prevTrack(ChordRest* cr)
      {
      if (!cr)
            return 0;

      ChordRest* el = 0;
      Measure* measure = cr->measure();
      int track = cr->track();

      while (!el) {
            // find next non-empty track
            while (--track >= 0){
                  if (measure->hasVoice(track))
                        break;
                  }
            // no more tracks, return original element
            if (track < 0)
                  return cr;
            // find element at same or previous segment within this track
            for (Segment* segment = cr->segment(); segment != 0; segment = segment->prev(Segment::SegChordRest)) {
                  el = static_cast<ChordRest*>(segment->element(track));
                  if (el)
                        break;
                  }
            }
      return el;
      }
Пример #22
0
void TestSpanners::spanners07()
{
    DropData    dropData;
    Glissando*  gliss;

    MasterScore* score = readScore(DIR + "glissando-cloning04.mscx");
    QVERIFY(score);
    score->doLayout();

    // DROP A GLISSANDO ON FIRST NOTE
    Measure*    msr   = score->firstMeasure();
    QVERIFY(msr);
    Segment*    seg   = msr->findSegment(Segment::Type::ChordRest, 0);
    QVERIFY(seg);
    Ms::Chord*      chord = static_cast<Ms::Chord*>(seg->element(0));
    QVERIFY(chord && chord->type() == Element::Type::CHORD);
    Note*       note  = chord->upNote();
    QVERIFY(note);
    // drop a glissando on note
    gliss             = new Glissando(score);
    dropData.pos      = note->pagePos();
    dropData.element  = gliss;
    note->drop(dropData);

    QVERIFY(saveCompareScore(score, "glissando-cloning04.mscx", DIR + "glissando-cloning04-ref.mscx"));
    delete score;
}
Пример #23
0
void ScoreView::lyricsEndEdit()
      {
      Lyrics* lyrics = toLyrics(editData.element);

      // if not empty, make sure this new lyrics does not fall in the middle
      // of an existing melisma from a previous lyrics; in case, shorten it
      int verse   = lyrics->no();
      Placement placement = lyrics->placement();
      int track   = lyrics->track();

      // search previous lyric
      Lyrics*  prevLyrics  = 0;
      Segment* prevSegment = lyrics->segment()->prev1(SegmentType::ChordRest);
      Segment* segment     = prevSegment;
      while (segment) {
            ChordRest* cr = toChordRest(segment->element(track));
            if (cr) {
                  prevLyrics = cr->lyrics(verse, placement);
                  if (prevLyrics)
                        break;
                  }
            segment = segment->prev1(SegmentType::ChordRest);
            }
      if (prevLyrics && prevLyrics->syllabic() == Lyrics::Syllabic::END) {
            int endTick = prevSegment->tick();      // a prev. melisma should not go beyond this segment
            if (prevLyrics->endTick() >= endTick)
                  prevLyrics->undoChangeProperty(Pid::LYRIC_TICKS, endTick - prevLyrics->segment()->tick());
            }
      }
Пример #24
0
Element* Rest::drop(const DropData& data)
      {
      Element* e = data.element;
      switch (e->type()) {
            case ARTICULATION:
                  if (e->subtype() == Articulation_Fermata)
                        score()->addArticulation(this, (Articulation*)e);
                  return 0;
            case ICON:
                  {
                  switch(e->subtype()) {
                        case ICON_SBEAM:
                              score()->undoChangeBeamMode(this, BEAM_BEGIN);
                              break;
                        case ICON_MBEAM:
                              score()->undoChangeBeamMode(this, BEAM_MID);
                              break;
                        case ICON_NBEAM:
                              score()->undoChangeBeamMode(this, BEAM_NO);
                              break;
                        case ICON_BEAM32:
                              score()->undoChangeBeamMode(this, BEAM_BEGIN32);
                              break;
                        case ICON_BEAM64:
                              score()->undoChangeBeamMode(this, BEAM_BEGIN64);
                              break;
                        case ICON_AUTOBEAM:
                              score()->undoChangeBeamMode(this, BEAM_AUTO);
                              break;
                        }
                  }
                  delete e;
                  break;

            case CHORD:
                  {
                  Chord* c      = static_cast<Chord*>(e);
                  Note* n       = c->upNote();
                  Direction dir = c->stemDirection();
                  score()->select(0, SELECT_SINGLE, 0);
                  NoteVal nval;
                  nval.pitch = n->pitch();
                  nval.headGroup = n->headGroup();
                  Fraction d = score()->inputState().duration().fraction();
                  if (!d.isZero()) {
                        Segment* seg = score()->setNoteRest(segment(), track(), nval, d, dir);
                        if (seg) {
                              ChordRest* cr = static_cast<ChordRest*>(seg->element(track()));
                              if (cr)
                                    score()->nextInputPos(cr, true);
                              }
                        }
                  delete e;
                  }
                  break;
            default:
                  return ChordRest::drop(data);
            }
      return 0;
      }
Пример #25
0
void TestTools::undoChangeVoice()
      {
      QString readFile(DIR + "undoChangeVoice.mscx");
      QString writeFile1("undoChangeVoice01-test.mscx");
      QString reference1(DIR  + "undoChangeVoice01-ref.mscx");
      QString writeFile2("undoChangeVoice02-test.mscx");
      QString reference2(DIR  + "undoChangeVoice02-ref.mscx");

      Score* score = readScore(readFile);
      score->doLayout();

      // do
      score->deselectAll();
      // select bottom note of all voice 1 chords
      for (Segment* s = score->firstSegment(Segment::Type::ChordRest); s; s = s->next1()) {
            ChordRest* cr = static_cast<ChordRest*>(s->element(0));
            if (cr && cr->type() == Element::Type::CHORD) {
                  Ms::Chord* c = static_cast<Ms::Chord*>(cr);
                  score->select(c->downNote(), SelectType::ADD);
                  }
            }
      // change voice
      score->changeVoice(1);
      QVERIFY(saveCompareScore(score, writeFile1, reference1));

      // undo
      score->undo()->undo();
      QVERIFY(saveCompareScore(score, writeFile2, reference2));

      delete score;
      }
Пример #26
0
bool areTiesConsistent(const Staff *staff)
      {
      const int strack = staff->idx() * VOICES;

      for (int voice = 0; voice < VOICES; ++voice) {
            bool isTie = false;
            for (Segment *seg = staff->score()->firstSegment(); seg; seg = seg->next1()) {
                  if (seg->segmentType() == Segment::Type::ChordRest) {
                        ChordRest *cr = static_cast<ChordRest *>(seg->element(strack + voice));

                        if (cr && cr->type() == Element::Type::REST && isTie) {
                              printInconsistentTieLocation(seg->measure()->no(), staff->idx());
                              return false;
                              }
                        if (isTiedBack(seg, strack, voice)) {
                              if (!isTie) {
                                    printInconsistentTieLocation(seg->measure()->no(), staff->idx());
                                    return false;
                                    }
                              isTie = false;
                              }
                        if (isTiedFor(seg, strack, voice)) {
                              if (isTie) {
                                    printInconsistentTieLocation(seg->measure()->no(), staff->idx());
                                    return false;
                                    }
                              isTie = true;
                              }
                        }
                  }
            if (isTie)
                  return false;
            }
      return true;
      }
Пример #27
0
QPointF Pedal::linePos(GripLine grip, System** sys) const
      {
      qreal x;
      qreal nhw = score()->noteHeadWidth();
      System* s = nullptr;
      if (grip == GripLine::START) {
            ChordRest* c = static_cast<ChordRest*>(startElement());
            s = c->segment()->system();
            x = c->pos().x() + c->segment()->pos().x() + c->segment()->measure()->pos().x();
            if (beginHook() && beginHookType() == HookType::HOOK_45)
                  x += nhw * .5;
            }
      else {
            ChordRest* c = nullptr;
            Element* e = endElement();
            if (!e || e == startElement()) {
                  // pedal marking on single note - extend to next note or end of measure
                  Segment* seg = startSegment();
                  if (seg) {
                        seg = seg->next();
                        for ( ; seg; seg = seg->next()) {
                              if (seg->segmentType() == Segment::Type::ChordRest) {
                                    if (seg->element(track()))
                                          break;
                                    }
                              else if (seg->segmentType() == Segment::Type::EndBarLine) {
                                    break;
                                    }
                              }
                        }
                  if (seg) {
                        s = seg->system();
                        x = seg->pos().x() + seg->measure()->pos().x() - nhw * 2;
                        }
                  }
            else {
                  c = static_cast<ChordRest*>(endElement());
                  if (c) {
                        s = c->segment()->system();
                        x = c->pos().x() + c->segment()->pos().x() + c->segment()->measure()->pos().x();
                        }
                  }
            if (!s) {
                  int t = tick2();
                  Measure* m = score()->tick2measure(t);
                  s = m->system();
                  x = m->tick2pos(t);
                  }
            if (endHook() && endHookType() == HookType::HOOK_45)
                  x += nhw * .5;
            else
                  x += nhw;
            }
      *sys = s;
      return QPointF(x, 0);
      }
Пример #28
0
void Ambitus::updateRange()
      {
      if (!segment())
            return;
      Chord* chord;
      int   firstTrack  = track();
      int   lastTrack   = firstTrack + VOICES-1;
      int   pitchTop    = -1000;
      int   pitchBottom = 1000;
      int   tpcTop      = 0;  // Initialized to prevent warning
      int   tpcBottom   = 0;  // Initialized to prevent warning
      int   trk;
      Measure* meas     = segment()->measure();
      Segment* segm     = meas->findSegment(SegmentType::ChordRest, segment()->tick());
      bool     stop     = meas->sectionBreak();
      while (segm) {
            // moved to another measure?
            if (segm->measure() != meas) {
                  // if section break has been found, stop here
                  if (stop)
                        break;
                  // update meas and stop condition
                  meas = segm->measure();
                  stop = meas->sectionBreak();
                  }
            // scan all relevant tracks of this segment for chords
            for (trk = firstTrack; trk <= lastTrack; trk++) {
                  Element* e = segm->element(trk);
                  if (!e || !e->isChord())
                        continue;
                  chord = toChord(e);
                  // update pitch range (with associated tpc's)
                  for (Note* n : chord->notes()) {
                        if (!n->play())         // skip notes which are not to be played
                              continue;
                        int pitch = n->ppitch();
                        if (pitch > pitchTop) {
                              pitchTop = pitch;
                              tpcTop   = n->tpc();
                              }
                        if (pitch < pitchBottom) {
                              pitchBottom = pitch;
                              tpcBottom   = n->tpc();
                              }
                        }
                  }
            segm = segm->nextCR();
            }

      if (pitchTop > -1000) {             // if something has been found, update this
            _topPitch    = pitchTop;
            _bottomPitch = pitchBottom;
            _topTpc      = tpcTop;
            _bottomTpc   = tpcBottom;
            }
      }
Пример #29
0
Element* Score::lastElement()
      {
      Element* re =0;
      Segment* seg = this->lastSegment();
      while (true) {
            for(int i = (this->staves().size() -1) * VOICES; i < this->staves().size() * VOICES; i++){
                  if(seg->element(i) != 0){
                        re = seg->element(i);
                        }
                  }
            if(re){
                  if(re->type() == Element::Type::CHORD){
                        return static_cast<Chord*>(re)->notes().first();
                        }
                  return re;
                  }
            seg = seg->prev1MM(Segment::Type::All);
            }
      }
Пример #30
0
Segment* InputState::nextInputPos() const
      {
      Measure* m = _segment->measure();
      Segment* s = _segment->next1(Segment::Type::ChordRest);
      for (; s; s = s->next1(Segment::Type::ChordRest)) {
            if (s->element(_track) || s->measure() != m)
                  return s;
            }
      return 0;
      }