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) {
                  Chord* c = static_cast<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;
      }
Exemple #2
0
void DrumTools::drumNoteSelected(int val)
      {
      Element* element = drumPalette->element(val);
      Chord* ch        = static_cast<Chord*>(element);
      Note* note       = ch->downNote();
      int ticks        = MScore::defaultPlayDuration;
      int pitch        = note->pitch();
      seq->startNote(staff->part()->instr()->channel(0), pitch, 80, ticks, 0.0);
      _score->inputState().setDrumNote(note->pitch());
      }
Exemple #3
0
int DrumTools::selectedDrumNote()
      {
      int idx = drumPalette->getSelectedIdx();
      if (idx < 0)
            return -1;
      Element* element = drumPalette->element(idx);
      if (element && element->type() == Element::Type::CHORD) {
            Chord* ch  = static_cast<Chord*>(element);
            Note* note = ch->downNote();
            return note->pitch();
            }
      else {
            return -1;
            }
      }
Exemple #4
0
QPointF Arpeggio::gripAnchor(int n) const
      {
      Chord* c = chord();
      if (c == 0)
            return QPointF();
      if (n == 0)
            return c->upNote()->pagePos();
      else if (n == 1) {
            Note* dnote = c->downNote();
            int btrack  = track() + (_span - 1) * VOICES;
            ChordRest* bchord = static_cast<ChordRest*>(c->segment()->element(btrack));
            if (bchord && bchord->type() == CHORD)
                  dnote = static_cast<Chord*>(bchord)->downNote();
            return dnote->pagePos();
            }
      return QPointF();
      }
Exemple #5
0
int DrumTools::selectedDrumNote()
      {
      int idx = drumPalette->getSelectedIdx();
      if (idx < 0)
            return -1;
      Element* element = drumPalette->element(idx);
      if (element && element->type() == ElementType::CHORD) {
            Chord* ch  = static_cast<Chord*>(element);
            Note* note = ch->downNote();
            auto pitchCell = drumPalette->cellAt(idx);
            pitchName->setText(pitchCell->name);
            return note->pitch();
            }
      else {
            return -1;
            }
      }
Exemple #6
0
void DrumTools::drumNoteSelected(int val)
      {
      Element* element = drumPalette->element(val);
      if(element && element->type() == CHORD) {
            Chord* ch        = static_cast<Chord*>(element);
            Note* note       = ch->downNote();
            int ticks        = MScore::defaultPlayDuration;
            int pitch        = note->pitch();
            seq->startNote(staff->part()->instr()->channel(0).channel, pitch, 80, ticks, 0.0);
            
            _score->inputState().setTrack(element->track());
            _score->inputState().setDrumNote(pitch);
            
            getAction("voice-1")->setChecked(element->voice() == 0);
            getAction("voice-2")->setChecked(element->voice() == 1);
            getAction("voice-3")->setChecked(element->voice() == 2);
            getAction("voice-4")->setChecked(element->voice() == 3);
            }
      }
Exemple #7
0
void Stem::layout()
      {
      qreal l = _len + _userLen;
      if (up())
            l = -l;
      Staff* st = staff();
      qreal lw5  = point(score()->styleS(ST_stemWidth)) * .5;
      QPointF p1(0.0, 0.0);
      QPointF p2(0.0, l);
      if (st) {
            // if TAB, use simplified positioning
            if (st->isTabStaff()) {
                  p1.rx() = -lw5;
                  p2.rx() = -lw5;
                  }
            // for any other staff type, use standard positioning
            else if (chord()) {
                  // adjust P1 for note head
                  Chord* c = chord();
                  if (c->up()) {
                        Note* n   = c->downNote();
                        p1 = symbols[score()->symIdx()][n->noteHead()].attach(n->magS());
                        p1.rx() = -lw5;
                        p2.rx() = -lw5;
                        }
                  else {
                        Note* n = c->upNote();
                        p1 = -symbols[score()->symIdx()][n->noteHead()].attach(n->magS());
                        p1.rx() = lw5;
                        p2.rx() = lw5;
                        }
                  }
            }
      line.setP1(p1);
      line.setP2(p2);

      // compute bounding rectangle
      QRectF r(line.p1(), line.p2());
      setbbox(r.normalized().adjusted(-lw5, -lw5, lw5, lw5));
      }
Exemple #8
0
void DrumTools::drumNoteSelected(int val)
      {
      Element* element = drumPalette->element(val);
      if (element && element->type() == ElementType::CHORD) {
            Chord* ch        = static_cast<Chord*>(element);
            Note* note       = ch->downNote();
            int ticks        = MScore::defaultPlayDuration;
            int pitch        = note->pitch();
            seq->startNote(staff->part()->instrument()->channel(0)->channel(), pitch, 80, ticks, 0.0);

            int track = (_score->inputState().track() / VOICES) * VOICES + element->track();
            _score->inputState().setTrack(track);
            _score->inputState().setDrumNote(pitch);

            getAction("voice-1")->setChecked(element->voice() == 0);
            getAction("voice-2")->setChecked(element->voice() == 1);
            getAction("voice-3")->setChecked(element->voice() == 2);
            getAction("voice-4")->setChecked(element->voice() == 3);

            auto pitchCell = drumPalette->cellAt(val);
            pitchName->setText(pitchCell->name);
            }
      }
Exemple #9
0
void Slur::slurPos(SlurPos* sp)
      {
      qreal _spatium = spatium();
      Element* e1 = startElement();
      Element* e2 = endElement();

      if (e2 == 0) {
            sp->p1 = e1->pagePos();
            sp->p1.rx() += e1->width();
            sp->p2 = sp->p1;
            sp->p2.rx() += 5 * _spatium;
            sp->system1 = static_cast<ChordRest*>(e1)->measure()->system();
            sp->system2 = sp->system1;
            return;
            }

      if ((e1->type() != CHORD) || (e2->type() != CHORD)) {
            sp->p1 = e1->pagePos();
            sp->p2 = e2->pagePos();
            sp->p1.rx() += e1->width();
            sp->p2.rx() += e2->width();
            sp->system1 = static_cast<ChordRest*>(e1)->measure()->system();
            sp->system2 = static_cast<ChordRest*>(e2)->measure()->system();
            return;
            }
      Chord* sc   = static_cast<Chord*>(e1);
      Chord* ec   = static_cast<Chord*>(e2);
      Note* note1 = _up ? sc->upNote() : sc->downNote();
      Note* note2 = _up ? ec->upNote() : ec->downNote();

      sp->system1 = sc->measure()->system();
      sp->system2 = ec->measure()->system();
      sp->p1      = sc->pagePos() - sp->system1->pagePos();
      sp->p2      = ec->pagePos() - sp->system2->pagePos();

      qreal xo, yo;

      Stem* stem1 = sc->stem();
      Stem* stem2 = ec->stem();

      enum SlurAnchor {
            SA_NONE, SA_STEM
            };
      SlurAnchor sa1 = SA_NONE;
      SlurAnchor sa2 = SA_NONE;
      if ((sc->up() == ec->up()) && !sc->beam() && !ec->beam() && (_up == sc->up())) {
            if (stem1)
                  sa1 = SA_STEM;
            if (stem2)
                  sa2 = SA_STEM;
            }

      qreal __up = _up ? -1.0 : 1.0;
      qreal hw   = note1->headWidth();
      switch (sa1) {
            case SA_STEM:
                  sp->p1 += sc->stemPosBeam() - sc->pagePos() + sc->stem()->p2();
                  sp->p1 += QPointF(0.35 * _spatium, 0.25 * _spatium);
                  break;
            case SA_NONE:
                  break;
            }
      switch(sa2) {
            case SA_STEM:
                  sp->p2 += ec->stemPosBeam() - ec->pagePos() + ec->stem()->p2();
                  sp->p2 += QPointF(-0.35 * _spatium, 0.25 * _spatium);
                  break;
            case SA_NONE:
                  break;
            }

      //
      // default position:
      //    horizontal: middle of note head
      //    vertical:   _spatium * .4 above/below note head
      //
      //------p1
      bool stemPos = false;   // p1 starts at chord stem side
      yo = note1->pos().y() + _spatium * .9 * __up;
      xo = hw * .5;

      if (stem1) {
            Beam* beam1 = sc->beam();
            if (beam1 && (beam1->elements().back() != sc) && (sc->up() == _up)) {
                  qreal sh = stem1->height() + _spatium;
                  yo       = sc->downNote()->pos().y() + sh * __up;
                  xo       = stem1->pos().x();
                  stemPos  = true;
                  }
            else {
                  if (sc->up() && _up)
                        xo = hw + _spatium * .3;
                  //
                  // handle case: stem up   - stem down
                  //              stem down - stem up
                  //
                  if ((sc->up() != ec->up()) && (sc->up() == _up)) {
                        Note* n1  = sc->up() ? sc->downNote() : sc->upNote();
                        Note* n2  = ec->up() ? ec->downNote() : ec->upNote();
                        qreal yd  = n2->pos().y() - n1->pos().y();

                        yd *= .5;

                        qreal sh = stem1->height();    // limit y move
                        if (yd > 0.0) {
                              if (yd > sh)
                                    yd = sh;
                              }
                        else {
                              if (yd < - sh)
                                    yd = -sh;
                              }
                        stemPos = true;
                        if ((_up && (yd < -_spatium)) || (!_up && (yd > _spatium)))
                              yo += yd;
                        }
                  else if (sc->up() != _up)
                        yo = fixArticulations(yo, sc, __up);
                  }
            }

      if (sa1 == SA_NONE)
            sp->p1 += QPointF(xo, yo);

      //------p2
      xo = hw * .5;
      yo = note2->pos().y() + _spatium * .9 * __up;

      if (stem2) {
            Beam* beam2 = ec->beam();
            if ((stemPos && (sc->up() == ec->up()))
               || (beam2
                 && (!beam2->elements().isEmpty())
                 && (beam2->elements().front() != ec)
                 && (ec->up() == _up)
                 && (sc->noteType() == NOTE_NORMAL)
                 )
                  ) {
                  qreal sh = stem2->height() + _spatium;
                  if (_up)
                        yo = ec->downNote()->pos().y() - sh;
                  else
                        yo = ec->upNote()->pos().y() + sh;
                  xo = stem2->pos().x();
                  }
            else if (!ec->up() && !_up)
                  xo = -_spatium * .3 + note2->x();
            //
            // handle case: stem up   - stem down
            //              stem down - stem up
            //
            if ((sc->up() != ec->up()) && (ec->up() == _up)) {
                  Note* n1 = sc->up() ? sc->downNote() : sc->upNote();
                  Note* n2 = ec->up() ? ec->downNote() : ec->upNote();
                  qreal yd = n2->pos().y() - n1->pos().y();

                  yd *= .5;

                  qreal mh = stem2->height();    // limit y move
                  if (yd > 0.0) {
                        if (yd > mh)
                              yd = mh;
                        }
                  else {
                        if (yd < - mh)
                              yd = -mh;
                        }

                  if ((_up && (yd > _spatium)) || (!_up && (yd < -_spatium)))
                        yo -= yd;
                  }
            else if (ec->up() != _up)
                  yo = fixArticulations(yo, ec, __up);
            }

      if (sa2 == SA_NONE)
            sp->p2 += QPointF(xo, yo);
      }
Exemple #10
0
void Fingering::layout()
      {
      if (parent()) {
            Fraction tick = parent()->tick();
            const Staff* st = staff();
            if (st && st->isTabStaff(tick) && !st->staffType(tick)->showTabFingering()) {
                  setbbox(QRectF());
                  return;
                  }
            }

      TextBase::layout();
      rypos() = 0.0;    // handle placement below

      if (autoplace() && note()) {
            Note* n      = note();
            Chord* chord = n->chord();
            bool voices  = chord->measure()->hasVoices(chord->staffIdx());
            bool tight   = voices && chord->notes().size() == 1 && !chord->beam() && tid() != Tid::STRING_NUMBER;

            qreal headWidth = n->bboxRightPos();

            // update offset after drag
            qreal rebase = 0.0;
            if (offsetChanged() != OffsetChange::NONE)
                  rebase = rebaseOffset();

            // temporarily exclude self from chord shape
            setAutoplace(false);

            if (layoutType() == ElementType::CHORD) {
                  Stem* stem = chord->stem();
                  Segment* s = chord->segment();
                  Measure* m = s->measure();
                  qreal sp = spatium();
                  qreal md = minDistance().val() * sp;
                  SysStaff* ss = m->system()->staff(chord->vStaffIdx());
                  Staff* vStaff = chord->staff();     // TODO: use current height at tick

                  if (n->mirror())
                        rxpos() -= n->ipos().x();
                  rxpos() += headWidth * .5;
                  if (placeAbove()) {
                        if (tight) {
                              if (chord->stem())
                                    rxpos() -= 0.8 * sp;
                              rypos() -= 1.5 * sp;
                              }
                        else {
                              QRectF r = bbox().translated(m->pos() + s->pos() + chord->pos() + n->pos() + pos());
                              SkylineLine sk(false);
                              sk.add(r.x(), r.bottom(), r.width());
                              qreal d = sk.minDistance(ss->skyline().north());
                              qreal yd = 0.0;
                              if (d > 0.0 && isStyled(Pid::MIN_DISTANCE))
                                    yd -= d + height() * .25;
                              // force extra space above staff & chord (but not other fingerings)
                              qreal top;
                              if (chord->up() && chord->beam() && stem) {
                                    top = stem->y() + stem->bbox().top();
                                    }
                              else {
                                    Note* un = chord->upNote();
                                    top = qMin(0.0, un->y() + un->bbox().top());
                                    }
                              top -= md;
                              qreal diff = (bbox().bottom() + ipos().y() + yd + n->y()) - top;
                              if (diff > 0.0)
                                    yd -= diff;
                              if (offsetChanged() != OffsetChange::NONE) {
                                    // user moved element within the skyline
                                    // we may need to adjust minDistance, yd, and/or offset
                                    bool inStaff = placeAbove() ? r.bottom() + rebase > 0.0 : r.top() + rebase < staff()->height();
                                    rebaseMinDistance(md, yd, sp, rebase, inStaff);
                                    }
                              rypos() += yd;
                              }
                        }
                  else {
                        if (tight) {
                              if (chord->stem())
                                    rxpos() += 0.8 * sp;
                              rypos() += 1.5 * sp;
                              }
                        else {
                              QRectF r = bbox().translated(m->pos() + s->pos() + chord->pos() + n->pos() + pos());
                              SkylineLine sk(true);
                              sk.add(r.x(), r.top(), r.width());
                              qreal d = ss->skyline().south().minDistance(sk);
                              qreal yd = 0.0;
                              if (d > 0.0 && isStyled(Pid::MIN_DISTANCE))
                                    yd += d + height() * .25;
                              // force extra space below staff & chord (but not other fingerings)
                              qreal bottom;
                              if (!chord->up() && chord->beam() && stem) {
                                    bottom = stem->y() + stem->bbox().bottom();
                                    }
                              else {
                                    Note* dn = chord->downNote();
                                    bottom = qMax(vStaff->height(), dn->y() + dn->bbox().bottom());
                                    }
                              bottom += md;
                              qreal diff = bottom - (bbox().top() + ipos().y() + yd + n->y());
                              if (diff > 0.0)
                                    yd += diff;
                              if (offsetChanged() != OffsetChange::NONE) {
                                    // user moved element within the skyline
                                    // we may need to adjust minDistance, yd, and/or offset
                                    bool inStaff = placeAbove() ? r.bottom() + rebase > 0.0 : r.top() + rebase < staff()->height();
                                    rebaseMinDistance(md, yd, sp, rebase, inStaff);
                                    }
                              rypos() += yd;
                              }
                        }
                  }
            else if (tid() == Tid::LH_GUITAR_FINGERING) {
                  // place to left of note
                  qreal left = n->shape().left();
                  if (left - n->x() > 0.0)
                        rxpos() -= left;
                  else
                        rxpos() -= n->x();
                  }
            // for other fingering styles, do not autoplace

            // restore autoplace
            setAutoplace(true);
            }
      else if (offsetChanged() != OffsetChange::NONE) {
            // rebase horizontally too, as autoplace may have adjusted it
            rebaseOffset(false);
            }
      setOffsetChanged(false);
      }