Example #1
0
static void addText(Score* score, int subtype, const QString& s)
{
    MeasureBase* measure = score->first();
    if (measure == 0 || measure->type() != VBOX) {
        score->insertMeasure(VBOX, measure);
        measure = score->first();
    }
    Text* text = new Text(score);
    switch(subtype) {
    case TEXT_TITLE:
        text->setTextStyleType(TEXT_STYLE_TITLE);
        break;
    case TEXT_SUBTITLE:
        text->setTextStyleType(TEXT_STYLE_SUBTITLE);
        break;
    case TEXT_COMPOSER:
        text->setTextStyleType(TEXT_STYLE_COMPOSER);
        break;
    case TEXT_POET:
        text->setTextStyleType(TEXT_STYLE_POET);
        break;
    }
    text->setParent(measure);
    text->setText(s);
    score->undoAddElement(text);
}
Example #2
0
void Page::doRebuildBspTree()
      {
      int n = 0;
      scanElements(&n, countElements, false);

      QRectF r;
      if (score()->layoutMode() == LayoutMode::LINE) {
            qreal w = 0.0;
            qreal h = 0.0;
            if (!_systems.empty()) {
                  h = _systems.front()->height();
                  if (!_systems.front()->measures().empty()) {
                        MeasureBase* mb = _systems.front()->measures().back();
                        w = mb->x() + mb->width();
                        }
                  }
            r = QRectF(0.0, 0.0, w, h);
            }
      else
            r = abbox();

      bspTree.initialize(r, n);
      scanElements(&bspTree, &bspInsert, false);
      bspTreeValid = true;
      }
Example #3
0
void Page::doRebuildBspTree()
      {
      QList<Element*> el;
      for (System* s : _systems) {
            for (MeasureBase* m : s->measures())
                  m->scanElements(&el, collectElements, false);
            }
      scanElements(&el, collectElements, false);

      int n = el.size();
      if (score()->layoutMode() == LayoutMode::LINE) {
            if (_systems.isEmpty())
                  return;
            if (_systems.front()->measures().isEmpty())
                  return;
            qreal h = _systems.front()->height();
            MeasureBase* mb = _systems.front()->measures().back();
            qreal w = mb->x() + mb->width();
            bspTree.initialize(QRectF(0.0, 0.0, w, h), n);
            }
      else
            bspTree.initialize(abbox(), n);
      for (int i = 0; i < n; ++i)
            bspTree.insert(el.at(i));
      bspTreeValid = true;
      }
Example #4
0
Measure* MeasureBase::nextMeasure() const
      {
      MeasureBase* m = _next;
      for (;;) {
            if (m == 0 || m->isMeasure())
                  break;
            m = m->_next;
            }
      return toMeasure(m);
      }
Example #5
0
Measure* MeasureBase::prevMeasure() const
      {
      MeasureBase* m = prev();
      while (m) {
            if (m->isMeasure())
                  return toMeasure(m);
            m = m->prev();
            }
      return 0;
      }
Example #6
0
int MeasureBase::index() const
      {
      int idx = 0;
      MeasureBase* m = score()->first();
      while (m) {
            if (m == this)
                  return idx;
            m = m->next();
            }
      return  -1;
      }
Example #7
0
MeasureBase* Score::tick2measureBase(int tick) const
      {
      for (MeasureBase* mb = first(); mb; mb = mb->next()) {
            int st = mb->tick();
            int l  = mb->ticks();
            if (tick >= st && tick < (st+l))
                  return mb;
            }
//      qDebug("tick2measureBase %d not found\n", tick);
      return 0;
      }
Example #8
0
Segment* Segment::prev1() const
      {
      if (prev())
            return prev();
      MeasureBase* m = measure();
      for (;;) {
            m = m->prev();
            if (m == 0)
                  return 0;
            if (m->type() == MEASURE)
                  return static_cast<Measure*>(m)->last();
            }
      }
Example #9
0
Segment* Segment::next1() const
      {
      if (next())
            return next();
      MeasureBase* m = measure();
      for (;;) {
            m = m->next();
            if (m == 0)
                  return 0;
            if (m->type() == MEASURE)
                  return static_cast<Measure*>(m)->first();
            }
      }
Example #10
0
void addTitleToScore(Score *score, const QString &string, int textCounter)
      {
      Text* text = new Text(score);
      if (textCounter == 1)
            text->setSubStyle(SubStyle::TITLE);
      else if (textCounter == 2)
            text->setSubStyle(SubStyle::COMPOSER);
      text->setPlainText(string.right(string.size() - TEXT_PREFIX.size()));

      MeasureBase* measure = score->first();
      if (measure->type() != Element::Type::VBOX) {
            measure = new VBox(score);
            measure->setTick(0);
            measure->setNext(score->first());
            score->measures()->add(measure);
            }
      measure->add(text);
      }
Example #11
0
ChordRest* Score::nextMeasure(ChordRest* element, bool selectBehavior)
      {
      if (!element)
            return 0;

      MeasureBase* mb = element->measure()->next();
      while (mb && ((mb->type() != Element::MEASURE) || (mb->type() == Element::MEASURE && static_cast<Measure*>(mb)->multiMeasure() < 0)))
            mb = mb->next();

      Measure* measure = static_cast<Measure*>(mb);

      int endTick = element->measure()->last()->nextChordRest(element->track(), true)->tick();
      bool last = false;

      if (selection().state() == SEL_RANGE) {
            if (element->tick() != endTick && selection().tickEnd() <= endTick) {
                  measure = element->measure();
                  last = true;
                  }
            else if (element->tick() == endTick && selection().isEndActive())
                  last = true;
            }
      else if (element->tick() != endTick && selectBehavior) {
            measure = element->measure();
            last = true;
            }
      if (!measure) {
            measure = element->measure();
            last = true;
            }
      int staff = element->staffIdx();

      Segment* startSeg = last ? measure->last() : measure->first();
      for (Segment* seg = startSeg; seg; seg = last ? seg->prev() : seg->next()) {
            int etrack = (staff+1) * VOICES;
            for (int track = staff * VOICES; track < etrack; ++track) {
                  Element* pel = seg->element(track);

                  if (pel && pel->isChordRest())
                        return static_cast<ChordRest*>(pel);
                  }
            }
      return 0;
      }
Example #12
0
Measure* MeasureBase::prevMeasureMM() const
      {
      MeasureBase* m = prev();
      while (m) {
            if (m->isMeasure()) {
                  Measure* mm = toMeasure(m);
                  if (score()->styleB(StyleIdx::createMultiMeasureRests)) {
                        if (mm->mmRestCount() >= 0) {
                              if (mm->hasMMRest())
                                    return mm->mmRest();
                              return mm;
                              }
                        }
                  else
                        return mm;
                  }
            m = m->prev();
            }
      return 0;
      }
void addTitleToScore(Score *score, const QString &string, int textCounter)
      {
      Tid ssid = Tid::DEFAULT;
      if (textCounter == 1)
            ssid = Tid::TITLE;
      else if (textCounter == 2)
            ssid = Tid::COMPOSER;

      Text* text = new Text(score, ssid);
      text->setPlainText(string.right(string.size() - int(TEXT_PREFIX.size())));

      MeasureBase* measure = score->first();
      if (!measure->isVBox()) {
            measure = new VBox(score);
            measure->setTick(0);
            measure->setNext(score->first());
            score->measures()->add(measure);
            }
      measure->add(text);
      }
Example #14
0
void Part::setStaves(int n)
      {
      int ns = _staves.size();
      if (n < ns) {
            printf("Part::setStaves(): remove staves not implemented!\n");
            return;
            }
      int staffIdx = _score->staffIdx(this) + ns;
      for (int i = ns; i < n; ++i) {
            Staff* staff = new Staff(_score, this, i);
            _staves.push_back(staff);
            _score->staves().insert(staffIdx, staff);
            for (MeasureBase* mb = _score->first(); mb; mb = mb->next()) {
                  if (mb->type() != MEASURE)
                        continue;
                  Measure* m = static_cast<Measure*>(mb);
                  m->insertStaff(staff, staffIdx);
                  }
            ++staffIdx;
            }
      }
Example #15
0
void addTitle(Score *score, const QString &string, int *textCounter)
      {
      if (string.left(TEXT_PREFIX.size()) == QString::fromStdString(TEXT_PREFIX)) {
            ++*textCounter;
            Text* text = new Text(score);
            if (*textCounter == 1)
                  text->setTextStyleType(TextStyleType::TITLE);
            else if (*textCounter == 2)
                  text->setTextStyleType(TextStyleType::COMPOSER);
            text->setText(string.right(string.size() - TEXT_PREFIX.size()));

            MeasureBase* measure = score->first();
            if (measure->type() != Element::Type::VBOX) {
                  measure = new VBox(score);
                  measure->setTick(0);
                  measure->setNext(score->first());
                  score->measures()->add(measure);
                  }
            measure->add(text);
            }
      }
Example #16
0
void PlayPanel::setScore(Score* s)
      {
      if (cs != 0 && cs == s)
            return;
      cs = s;
      if (cs) {
            MeasureBase* lm = cs->last();
            if (lm)
                  setEndpos(lm->tick() + lm->ticks());
            }
      bool enable = cs != 0;
      volumeSlider->setEnabled(enable);
      posSlider->setEnabled(enable);
      tempoSlider->setEnabled(enable);
      swingStyle->setEnabled(enable);
      if (cs) {
            setTempo(cs->tempomap()->tempo(0));
            setRelTempo(cs->tempomap()->relTempo());
            Measure* m = cs->lastMeasure();
            if (m)
                  setEndpos(m ? m->tick() + m->ticks() : 0);
            int tick = cs->playPos();
            heartBeat(tick, tick);
            }
      else {
            setTempo(120.0);
            setRelTempo(1.0);
            setEndpos(0);
            heartBeat(0, 0);
            }
//      heartBeat2(seq->getCurTime());
//      int tick, utick;
//      seq->getCurTick(&tick, &utick);
//      heartBeat(tick, utick);
      update();
      }
Example #17
0
void Score::readStaff(XmlReader& e)
      {
      int staff = e.intAttribute("id", 1) - 1;
      int measureIdx = 0;
      e.setCurrentMeasureIndex(0);
      e.initTick(0);
      e.setTrack(staff * VOICES);

      if (staff == 0) {
            while (e.readNextStartElement()) {
                  const QStringRef& tag(e.name());

                  if (tag == "Measure") {
                        Measure* measure = 0;
                        measure = new Measure(this);
                        measure->setTick(e.tick());
                        e.setCurrentMeasureIndex(measureIdx++);
                        //
                        // inherit timesig from previous measure
                        //
                        Measure* m = e.lastMeasure(); // measure->prevMeasure();
                        Fraction f(m ? m->timesig() : Fraction(4,4));
                        measure->setLen(f);
                        measure->setTimesig(f);

                        measure->read(e, staff);
                        measure->checkMeasure(staff);
                        if (!measure->isMMRest()) {
                              measures()->add(measure);
                              e.setLastMeasure(measure);
                              e.initTick(measure->tick() + measure->ticks());
                              }
                        else {
                              // this is a multi measure rest
                              // always preceded by the first measure it replaces
                              Measure* m1 = e.lastMeasure();

                              if (m1) {
                                    m1->setMMRest(measure);
                                    measure->setTick(m1->tick());
                                    }
                              }
                        }
                  else if (tag == "HBox" || tag == "VBox" || tag == "TBox" || tag == "FBox") {
                        MeasureBase* mb = toMeasureBase(Element::name2Element(tag, this));
                        mb->read(e);
                        mb->setTick(e.tick());
                        measures()->add(mb);
                        }
                  else if (tag == "tick")
                        e.initTick(fileDivision(e.readInt()));
                  else
                        e.unknown();
                  }
            }
      else {
            Measure* measure = firstMeasure();
            while (e.readNextStartElement()) {
                  const QStringRef& tag(e.name());

                  if (tag == "Measure") {
                        if (measure == 0) {
                              qDebug("Score::readStaff(): missing measure!");
                              measure = new Measure(this);
                              measure->setTick(e.tick());
                              measures()->add(measure);
                              }
                        e.initTick(measure->tick());
                        e.setCurrentMeasureIndex(measureIdx++);
                        measure->read(e, staff);
                        measure->checkMeasure(staff);
                        if (measure->isMMRest())
                              measure = e.lastMeasure()->nextMeasure();
                        else {
                              e.setLastMeasure(measure);
                              if (measure->mmRest())
                                    measure = measure->mmRest();
                              else
                                    measure = measure->nextMeasure();
                              }
                        }
                  else if (tag == "tick")
                        e.initTick(fileDivision(e.readInt()));
                  else
                        e.unknown();
                  }
            }
      }
Example #18
0
void Score::write(Xml& xml, bool selectionOnly)
{
    // if we have multi measure rests and some parts are hidden,
    // then some layout information is missing:
    // relayout with all parts set visible

    QList<Part*> hiddenParts;
    bool unhide = false;
    if (styleB(StyleIdx::createMultiMeasureRests)) {
        for (Part* part : _parts) {
            if (!part->show()) {
                if (!unhide) {
                    startCmd();
                    unhide = true;
                }
                part->undoChangeProperty(P_ID::VISIBLE, true);
                hiddenParts.append(part);
            }
        }
    }
    if (unhide) {
        doLayout();
        for (Part* p : hiddenParts)
            p->setShow(false);
    }

    xml.stag("Score");
    switch(_layoutMode) {
    case LayoutMode::PAGE:
    case LayoutMode::FLOAT:
    case LayoutMode::SYSTEM:
        break;
    case LayoutMode::LINE:
        xml.tag("layoutMode", "line");
        break;
    }

#ifdef OMR
    if (_omr && xml.writeOmr)
        _omr->write(xml);
#endif
    if (_showOmr && xml.writeOmr)
        xml.tag("showOmr", _showOmr);
    if (_audio && xml.writeOmr) {
        xml.tag("playMode", int(_playMode));
        _audio->write(xml);
    }

    for (int i = 0; i < 32; ++i) {
        if (!_layerTags[i].isEmpty()) {
            xml.tag(QString("LayerTag id=\"%1\" tag=\"%2\"").arg(i).arg(_layerTags[i]),
                    _layerTagComments[i]);
        }
    }
    int n = _layer.size();
    for (int i = 1; i < n; ++i) {       // dont save default variant
        const Layer& l = _layer[i];
        xml.tagE(QString("Layer name=\"%1\" mask=\"%2\"").arg(l.name).arg(l.tags));
    }
    xml.tag("currentLayer", _currentLayer);

    if (!MScore::testMode)
        _synthesizerState.write(xml);

    if (pageNumberOffset())
        xml.tag("page-offset", pageNumberOffset());
    xml.tag("Division", MScore::division);
    xml.curTrack = -1;

    _style.save(xml, true);      // save only differences to buildin style

    xml.tag("showInvisible", _showInvisible);
    xml.tag("showUnprintable", _showUnprintable);
    xml.tag("showFrames", _showFrames);
    xml.tag("showMargins", _showPageborders);

    QMapIterator<QString, QString> i(_metaTags);
    while (i.hasNext()) {
        i.next();
        if ((!MScore::testMode  && !MScore::saveTemplateMode) || (i.key() != "platform" && i.key() != "creationDate"))
            xml.tag(QString("metaTag name=\"%1\"").arg(i.key().toHtmlEscaped()), i.value());
    }

    if (!selectionOnly) {
        xml.stag("PageList");
        foreach(Page* page, _pages)
            page->write(xml);
        xml.etag();
    }

    xml.curTrack = 0;
    int staffStart;
    int staffEnd;
    MeasureBase* measureStart;
    MeasureBase* measureEnd;

    if (selectionOnly) {
        staffStart   = _selection.staffStart();
        staffEnd     = _selection.staffEnd();
        // make sure we select full parts
        Staff* sStaff = staff(staffStart);
        Part* sPart = sStaff->part();
        Staff* eStaff = staff(staffEnd - 1);
        Part* ePart = eStaff->part();
        staffStart = staffIdx(sPart);
        staffEnd = staffIdx(ePart) + ePart->nstaves();
        measureStart = _selection.startSegment()->measure();
        if (_selection.endSegment())
            measureEnd   = _selection.endSegment()->measure()->next();
        else
            measureEnd   = 0;
    }
    else {
        staffStart   = 0;
        staffEnd     = nstaves();
        measureStart = first();
        measureEnd   = 0;
    }

    foreach(const Part* part, _parts) {
        if (!selectionOnly || ((staffIdx(part) >= staffStart) && (staffEnd >= staffIdx(part) + part->nstaves())))
            part->write(xml);
    }

    xml.curTrack = 0;
    xml.trackDiff = -staffStart * VOICES;
    if (measureStart) {
        for (int staffIdx = staffStart; staffIdx < staffEnd; ++staffIdx) {
            xml.stag(QString("Staff id=\"%1\"").arg(staffIdx + 1 - staffStart));
            xml.curTick  = measureStart->tick();
            xml.tickDiff = xml.curTick;
            xml.curTrack = staffIdx * VOICES;
            bool writeSystemElements = staffIdx == staffStart;
            for (MeasureBase* m = measureStart; m != measureEnd; m = m->next())
                writeMeasure(xml, m, staffIdx, writeSystemElements);
            xml.etag();
        }
    }
    xml.curTrack = -1;
    if (!selectionOnly) {
        for (const Excerpt* excerpt : _excerpts) {
            if (excerpt->partScore() != this)
                excerpt->partScore()->write(xml, false);       // recursion
        }
    }
    if (parentScore())
        xml.tag("name", name());
    xml.etag();

    if (unhide) {
        endCmd();
        undo()->undo();
        endUndoRedo();
    }
}
Example #19
0
void MTrack::processMeta(int tick, const MidiEvent& mm)
      {
      if (!staff) {
            qDebug("processMeta: no staff");
            return;
            }
      const uchar* data = (uchar*)mm.edata();
      int staffIdx      = staff->idx();
      Score* cs         = staff->score();

      switch (mm.metaType()) {
            case META_TEXT:
            case META_LYRIC: {
                  QString s((char*)data);
                  cs->addLyrics(tick, staffIdx, s);
                  }
                  break;

            case META_TRACK_NAME:
                  name = (const char*)data;
                  break;

            case META_TEMPO:
                  {
                  unsigned tempo = data[2] + (data[1] << 8) + (data[0] <<16);
                  double t = 1000000.0 / double(tempo);
                  cs->setTempo(tick, t);
                  // TODO: create TempoText
                  }
                  break;

            case META_KEY_SIGNATURE:
                  {
                  int key = ((const char*)data)[0];
                  if (key < -7 || key > 7) {
                        qDebug("ImportMidi: illegal key %d", key);
                        break;
                        }
                  KeySigEvent ks;
                  ks.setAccidentalType(key);
                  (*staff->keymap())[tick] = ks;
                  hasKey = true;
                  }
                  break;
            case META_COMPOSER:     // mscore extension
            case META_POET:
            case META_TRANSLATOR:
            case META_SUBTITLE:
            case META_TITLE:
                  {
                  Text* text = new Text(cs);
                  switch(mm.metaType()) {
                        case META_COMPOSER:
                              text->setTextStyleType(TEXT_STYLE_COMPOSER);
                              break;
                        case META_TRANSLATOR:
                              text->setTextStyleType(TEXT_STYLE_TRANSLATOR);
                              break;
                        case META_POET:
                              text->setTextStyleType(TEXT_STYLE_POET);
                              break;
                        case META_SUBTITLE:
                              text->setTextStyleType(TEXT_STYLE_SUBTITLE);
                              break;
                        case META_TITLE:
                              text->setTextStyleType(TEXT_STYLE_TITLE);
                              break;
                        }

                  text->setText((const char*)(mm.edata()));

                  MeasureBase* measure = cs->first();
                  if (measure->type() != Element::VBOX) {
                        measure = new VBox(cs);
                        measure->setTick(0);
                        measure->setNext(cs->first());
                        cs->add(measure);
                        }
                  measure->add(text);
                  }
                  break;

            case META_COPYRIGHT:
                  cs->setMetaTag("Copyright", QString((const char*)(mm.edata())));
                  break;

            case META_TIME_SIGNATURE:
                  qDebug("midi: meta timesig: %d, division %d", tick, MScore::division);
                  cs->sigmap()->add(tick, Fraction(data[0], 1 << data[1]));
                  break;

            default:
                  if (MScore::debugMode)
                        qDebug("unknown meta type 0x%02x", mm.metaType());
                  break;
            }
      }
Example #20
0
void System::layout2()
      {
      if (isVbox())                 // ignore vbox
            return;

      int nstaves    = _staves.size();
      qreal _spatium = spatium();

      qreal y = 0.0;
      int lastStaffIdx  = 0;   // last visible staff
      int firstStaffIdx = -1;
      qreal lastStaffDistanceDown = 0.0;
      for (int staffIdx = 0; staffIdx < nstaves; ++staffIdx) {
            Staff* staff = score()->staff(staffIdx);
            StyleIdx downDistance;
            qreal userDist = 0.0;
            if ((staffIdx + 1) == nstaves) {
                  //
                  // last staff in system
                  //
                  MeasureBase* mb = ml.last();
                  bool nextMeasureIsVBOX = false;
                  if (mb->next()) {
                        Element::Type type = mb->next()->type();
                        if (type == Element::Type::VBOX || type == Element::Type::TBOX || type == Element::Type::FBOX)
                              nextMeasureIsVBOX = true;
                        }
                  downDistance = nextMeasureIsVBOX ? StyleIdx::systemFrameDistance : StyleIdx::minSystemDistance;
                  }
            else if (staff->rstaff() < (staff->part()->staves()->size()-1)) {
                  //
                  // staff is not last staff in a part
                  //
                  downDistance = StyleIdx::akkoladeDistance;
                  userDist = score()->staff(staffIdx + 1)->userDist();
                  }
            else {
                  downDistance = StyleIdx::staffDistance;
                  userDist = score()->staff(staffIdx + 1)->userDist();
                  }

            SysStaff* s    = _staves[staffIdx];
            qreal distDown = score()->styleS(downDistance).val() * _spatium + userDist;
            qreal nominalDistDown = distDown;
            qreal distUp   = 0.0;
            int n = ml.size();
            for (int i = 0; i < n; ++i) {
                  MeasureBase* m = ml.at(i);
                  distDown = qMax(distDown, m->distanceDown(staffIdx));
                  distUp   = qMax(distUp,   m->distanceUp(staffIdx));
                  }
            s->setDistanceDown(distDown);
            s->setDistanceUp(distUp);

            if (!staff->show() || !s->show()) {
                  s->setbbox(QRectF());  // already done in layout() ?
                  continue;
                  }
            qreal sHeight = staff->height();
            qreal dup = staffIdx == 0 ? 0.0 : s->distanceUp();
            if (staff->lines() == 1)
                  dup -= _spatium * staff->mag();
            s->bbox().setRect(_leftMargin, y + dup, width() - _leftMargin, sHeight);
            y += dup + sHeight + s->distanceDown();
            lastStaffIdx = staffIdx;
            lastStaffDistanceDown = distDown - nominalDistDown;
            if (firstStaffIdx == -1)
                  firstStaffIdx = staffIdx;
            }
      if (firstStaffIdx == -1)
            firstStaffIdx = 0;

      qreal systemHeight = staff(lastStaffIdx)->bbox().bottom();
      if (lastStaffIdx < nstaves - 1)
            systemHeight += lastStaffDistanceDown;
      setHeight(systemHeight);

      int n = ml.size();
      for (int i = 0; i < n; ++i) {
            MeasureBase* m = ml.at(i);
            if (m->type() == Element::Type::MEASURE) {
                  // note that the factor 2 * _spatium must be corrected for when exporting
                  // system distance in MusicXML (issue #24733)
                  m->bbox().setRect(0.0, -_spatium, m->width(), systemHeight + 2 * _spatium);
                  }
            else if (m->type() == Element::Type::HBOX) {
                  m->bbox().setRect(0.0, 0.0, m->width(), systemHeight);
                  static_cast<HBox*>(m)->layout2();
                  }
            }

      if (_barLine) {
            _barLine->setTrack(firstStaffIdx * VOICES);
            _barLine->setSpan(lastStaffIdx - firstStaffIdx + 1);
            if (score()->staff(0)->lines() == 1)
                  _barLine->setSpanFrom(BARLINE_SPAN_1LINESTAFF_FROM);

            int spanTo = (score()->staff(lastStaffIdx)->lines() == 1) ?
                              BARLINE_SPAN_1LINESTAFF_TO :
                              (score()->staff(lastStaffIdx)->lines()-1)*2;
            _barLine->setSpanTo(spanTo);
            _barLine->layout();
            }

      //---------------------------------------------------
      //  layout brackets vertical position
      //---------------------------------------------------

      n = _brackets.size();
      for (int i = 0; i < n; ++i) {
            Bracket* b = _brackets.at(i);
            int staffIdx1 = b->firstStaff();
            int staffIdx2 = b->lastStaff();
            qreal sy = 0;                       // assume bracket not visible
            qreal ey = 0;
            // if start staff not visible, try next staff
            while (staffIdx1 <= staffIdx2 && !_staves[staffIdx1]->show())
                  ++staffIdx1;
            // if end staff not visible, try prev staff
            while (staffIdx1 <= staffIdx2 && !_staves[staffIdx2]->show())
                  --staffIdx2;
            // the bracket will be shown IF:
            // it spans at least 2 visible staves (staffIdx1 < staffIdx2) OR
            // it spans just one visible staff (staffIdx1 == staffIdx2) but it is required to do so
            // (the second case happens at least when the bracket is initially dropped)
            bool notHidden = (staffIdx1 < staffIdx2) || (b->span() == 1 && staffIdx1 == staffIdx2);
            if (notHidden) {                    // set vert. pos. and height to visible spanned staves
                  sy = _staves[staffIdx1]->bbox().top();
                  ey = _staves[staffIdx2]->bbox().bottom();
                  }
            b->rypos() = sy;
            b->setHeight(ey - sy);
            b->layout();
            }

      //---------------------------------------------------
      //  layout instrument names
      //---------------------------------------------------

      int staffIdx = 0;
      n = score()->parts().size();

      for (Part* p : score()->parts()) {
            SysStaff* s = staff(staffIdx);
            SysStaff* s2;
            int nstaves = p->nstaves();
            if (s->show()) {
                  for (InstrumentName* t : s->instrumentNames) {
                        //
                        // override Text->layout()
                        //
                        qreal y1, y2;
                        switch (t->layoutPos()) {
                              default:
                              case 0:           // center at part
                                    y1 = s->bbox().top();
                                    s2 = staff(staffIdx);
                                    for (int i = staffIdx + nstaves - 1; i > 0; --i) {
                                          SysStaff* s = staff(i);
                                          if (s->show()) {
                                                s2 = s;
                                                break;
                                                }
                                          }
                                    y2 = s2->bbox().bottom();
                                    break;
                              case 1:           // center at first staff
                                    y1 = s->bbox().top();
                                    y2 = s->bbox().bottom();
                                    break;

                              // TODO:
                              // sort out invisible staves

                              case 2:           // center between first and second staff
                                    y1 = s->bbox().top();
                                    y2 = staff(staffIdx + 1)->bbox().bottom();
                                    break;
                              case 3:           // center at second staff
                                    y1 = staff(staffIdx + 1)->bbox().top();
                                    y2 = staff(staffIdx + 1)->bbox().bottom();
                                    break;
                              case 4:           // center between first and second staff
                                    y1 = staff(staffIdx + 1)->bbox().top();
                                    y2 = staff(staffIdx + 2)->bbox().bottom();
                                    break;
                              case 5:           // center at third staff
                                    y1 = staff(staffIdx + 2)->bbox().top();
                                    y2 = staff(staffIdx + 2)->bbox().bottom();
                                    break;
                              }
                        t->rypos() = y1 + (y2 - y1) * .5 + t->textStyle().offset(t->spatium()).y();
                        }
                  }
            staffIdx += nstaves;
            }
      }
Example #21
0
Score::FileError Score::read114(XmlReader& e)
      {
      if (parentScore())
            setMscVersion(parentScore()->mscVersion());

      for (unsigned int i = 0; i < sizeof(style114)/sizeof(*style114); ++i)
            style()->set(style114[i].idx, style114[i].val);

      // old text style defaults
      TextStyle ts = style()->textStyle("Chord Symbol");
      ts.setYoff(-4.0);
      style()->setTextStyle(ts);
      TempoMap tm;
      while (e.readNextStartElement()) {
            e.setTrack(-1);
            const QStringRef& tag(e.name());
            if (tag == "Staff")
                  readStaff(e);
            else if (tag == "KeySig") {               // not supported
                  KeySig* ks = new KeySig(this);
                  ks->read(e);
                  // customKeysigs.append(ks);
                  delete ks;
                  }
            else if (tag == "siglist")
                  _sigmap->read(e, _fileDivision);
            else if (tag == "programVersion") {
                  _mscoreVersion = e.readElementText();
                  parseVersion(_mscoreVersion);
                  }
            else if (tag == "programRevision")
                  _mscoreRevision = e.readInt();
            else if (tag == "Mag"
               || tag == "MagIdx"
               || tag == "xoff"
               || tag == "Symbols"
               || tag == "cursorTrack"
               || tag == "yoff")
                  e.skipCurrentElement();       // obsolete
            else if (tag == "tempolist") {
                  // store the tempo list to create invisible tempo text later
                  qreal tempo = e.attribute("fix","2.0").toDouble();
                  tm.setRelTempo(tempo);
                  while (e.readNextStartElement()) {
                        if (e.name() == "tempo") {
                              int tick = e.attribute("tick").toInt();
                              double tmp = e.readElementText().toDouble();
                              tick = (tick * MScore::division + _fileDivision/2) / _fileDivision;
                              auto pos = tm.find(tick);
                              if (pos != tm.end())
                                    tm.erase(pos);
                              tm.setTempo(tick, tmp);
                        }
                        else if (e.name() == "relTempo")
                              e.readElementText();
                        else
                              e.unknown();
                  }
            }
            else if (tag == "playMode")
                  _playMode = PlayMode(e.readInt());
            else if (tag == "SyntiSettings")
                  _synthesizerState.read(e);
            else if (tag == "Spatium")
                  _style.setSpatium (e.readDouble() * MScore::DPMM);
            else if (tag == "Division")
                  _fileDivision = e.readInt();
            else if (tag == "showInvisible")
                  _showInvisible = e.readInt();
            else if (tag == "showFrames")
                  _showFrames = e.readInt();
            else if (tag == "showMargins")
                  _showPageborders = e.readInt();
            else if (tag == "Style") {
                  qreal sp = _style.spatium();
                  _style.load(e);
                  // adjust this now so chords render properly on read
                  // other style adjustments can wait until reading is finished
                  if (style(StyleIdx::useGermanNoteNames).toBool())
                        style()->set(StyleIdx::useStandardNoteNames, false);
                  if (_layoutMode == LayoutMode::FLOAT) {
                        // style should not change spatium in
                        // float mode
                        _style.setSpatium(sp);
                        }
                  }
            else if (tag == "TextStyle") {
                  TextStyle s;
                  s.read(e);

                  qreal spMM = _style.spatium() / MScore::DPMM;
                  if (s.frameWidthMM() != 0.0)
                        s.setFrameWidth(Spatium(s.frameWidthMM() / spMM));
                  if (s.paddingWidthMM() != 0.0)
                        s.setPaddingWidth(Spatium(s.paddingWidthMM() / spMM));
\
                  // convert 1.2 text styles
                  s.setName(convertOldTextStyleNames(s.name()));

                  if (s.name() == "Lyrics Odd Lines" || s.name() == "Lyrics Even Lines")
                        s.setAlign((s.align() & ~ Align(AlignmentFlags::VMASK)) | AlignmentFlags::BASELINE);

                  _style.setTextStyle(s);
                  }
            else if (tag == "page-layout") {
                  if (_layoutMode != LayoutMode::FLOAT && _layoutMode != LayoutMode::SYSTEM) {
                        PageFormat pf;
                        pf.copy(*pageFormat());
                        pf.read(e, this);
                        setPageFormat(pf);
                        }
                  else
                        e.skipCurrentElement();
                  }
            else if (tag == "copyright" || tag == "rights") {
                  Text* text = new Text(this);
                  text->read(e);
                  text->layout();
                  setMetaTag("copyright", text->plainText());
                  delete text;
                  }
            else if (tag == "movement-number")
                  setMetaTag("movementNumber", e.readElementText());
            else if (tag == "movement-title")
                  setMetaTag("movementTitle", e.readElementText());
            else if (tag == "work-number")
                  setMetaTag("workNumber", e.readElementText());
            else if (tag == "work-title")
                  setMetaTag("workTitle", e.readElementText());
            else if (tag == "source")
                  setMetaTag("source", e.readElementText());
            else if (tag == "metaTag") {
                  QString name = e.attribute("name");
                  setMetaTag(name, e.readElementText());
                  }
            else if (tag == "Part") {
                  Part* part = new Part(this);
                  part->read114(e);
                  _parts.push_back(part);
                  }
            else if (tag == "Slur") {
                  Slur* slur = new Slur(this);
                  slur->read(e);
                  addSpanner(slur);
                  }
            else if ((tag == "HairPin")
                || (tag == "Ottava")
                || (tag == "TextLine")
                || (tag == "Volta")
                || (tag == "Trill")
                || (tag == "Pedal")) {
                  Spanner* s = static_cast<Spanner*>(Element::name2Element(tag, this));
                  s->read(e);
                  if (s->track() == -1)
                        s->setTrack(e.track());
                  else
                        e.setTrack(s->track());       // update current track
                  if (s->tick() == -1)
                        s->setTick(e.tick());
                  else
                        e.initTick(s->tick());      // update current tick
                  if (s->track2() == -1)
                        s->setTrack2(s->track());
                  if (s->ticks() == 0) {
                        delete s;
                        qDebug("zero spanner %s ticks: %d", s->name(), s->ticks());
                        }
                  else {
                        addSpanner(s);
                        }
                  }
            else if (tag == "Excerpt") {
                  if (MScore::noExcerpts)
                        e.skipCurrentElement();
                  else {
                        Excerpt* ex = new Excerpt(this);
                        ex->read(e);
                        _excerpts.append(ex);
                        }
                  }
            else if (tag == "Beam") {
                  Beam* beam = new Beam(this);
                  beam->read(e);
                  beam->setParent(0);
                  // _beams.append(beam);
                  }
            else if (tag == "name")
                  setName(e.readElementText());
            else
                  e.unknown();
            }

      if (e.error() != XmlStreamReader::NoError)
            return FileError::FILE_BAD_FORMAT;

      int n = nstaves();
      for (int idx = 0; idx < n; ++idx) {
            Staff* s = _staves[idx];
            int track = idx * VOICES;

            // check barLineSpan
            if (s->barLineSpan() > (n - idx)) {
                  qDebug("read114: invalid bar line span %d (max %d)",
                     s->barLineSpan(), n - idx);
                  s->setBarLineSpan(n - idx);
                  }
            for (auto i : e.clefs(idx)) {
                  int tick = i.first;
                  ClefType clefId = i.second;
                  Measure* m = tick2measure(tick);
                  if (!m)
                        continue;
                  if ((tick == m->tick()) && m->prevMeasure())
                        m = m->prevMeasure();
                  Segment* seg = m->getSegment(Segment::Type::Clef, tick);
                  if (seg->element(track))
                        static_cast<Clef*>(seg->element(track))->setGenerated(false);
                  else {
                        Clef* clef = new Clef(this);
                        clef->setClefType(clefId);
                        clef->setTrack(track);
                        clef->setParent(seg);
                        clef->setGenerated(false);
                        seg->add(clef);
                        }
                  }

            // create missing KeySig
            KeyList* km = s->keyList();
            for (auto i = km->begin(); i != km->end(); ++i) {
                  int tick = i->first;
                  if (tick < 0) {
                        qDebug("read114: Key tick %d", tick);
                        continue;
                        }
                  if (tick == 0 && i->second.key() == Key::C)
                        continue;
                  Measure* m = tick2measure(tick);
                  if (!m)           //empty score
                        break;
                  Segment* seg = m->getSegment(Segment::Type::KeySig, tick);
                  if (seg->element(track))
                        static_cast<KeySig*>(seg->element(track))->setGenerated(false);
                  else {
                        KeySigEvent ke = i->second;
                        KeySig* ks = new KeySig(this);
                        ks->setKeySigEvent(ke);
                        ks->setParent(seg);
                        ks->setTrack(track);
                        ks->setGenerated(false);
                        seg->add(ks);
                        }
                  }
            }

      for (std::pair<int,Spanner*> p : spanner()) {
            Spanner* s = p.second;
            if (s->type() != Element::Type::SLUR) {
                  if (s->type() == Element::Type::VOLTA) {
                        Volta* volta = static_cast<Volta*>(s);
                        volta->setAnchor(Spanner::Anchor::MEASURE);
                        }
                  }

            if (s->type() == Element::Type::OTTAVA
                || s->type() == Element::Type::PEDAL
                || s->type() == Element::Type::TRILL
                || s->type() == Element::Type::TEXTLINE) {
                  qreal yo = 0;
                  if (s->type() == Element::Type::OTTAVA) {
                      // fix ottava position
                      yo = styleS(StyleIdx::ottavaY).val() * spatium();
                      if (s->placement() == Element::Placement::BELOW)
                            yo = -yo + s->staff()->height();
                      }
                  else if (s->type() == Element::Type::PEDAL) {
                        yo = styleS(StyleIdx::pedalY).val() * spatium();
                        }
                  else if (s->type() == Element::Type::TRILL) {
                        yo = styleS(StyleIdx::trillY).val() * spatium();
                        }
                  else if (s->type() == Element::Type::TEXTLINE) {
                        yo = -5.0 * spatium();
                  }
                  if (!s->spannerSegments().isEmpty()) {
                        for (SpannerSegment* seg : s->spannerSegments()) {
                              if (!seg->userOff().isNull())
                                    seg->setUserYoffset(seg->userOff().y() - yo);
                              }
                        }
                  else {
                        s->setUserYoffset(-yo);
                        }
                  }
            }

      connectTies();

      //
      // remove "middle beam" flags from first ChordRest in
      // measure
      //
      for (Measure* m = firstMeasure(); m; m = m->nextMeasure()) {
            int tracks = nstaves() * VOICES;
            bool first = true;
            for (int track = 0; track < tracks; ++track) {
                  for (Segment* s = m->first(); s; s = s->next()) {
                        if (s->segmentType() != Segment::Type::ChordRest)
                              continue;
                        ChordRest* cr = static_cast<ChordRest*>(s->element(track));
                        if (cr) {
                              if(cr->type() == Element::Type::REST) {
                                    Rest* r = static_cast<Rest*>(cr);
                                    if (!r->userOff().isNull()) {
                                          int lineOffset = r->computeLineOffset();
                                          qreal lineDist = r->staff() ? r->staff()->staffType()->lineDistance().val() : 1.0;
                                          r->rUserYoffset() -= (lineOffset * .5 * lineDist * r->spatium());
                                          }
                                    }
                              if(!first) {
                                    switch(cr->beamMode()) {
                                          case Beam::Mode::AUTO:
                                          case Beam::Mode::BEGIN:
                                          case Beam::Mode::END:
                                          case Beam::Mode::NONE:
                                                break;
                                          case Beam::Mode::MID:
                                          case Beam::Mode::BEGIN32:
                                          case Beam::Mode::BEGIN64:
                                                cr->setBeamMode(Beam::Mode::BEGIN);
                                                break;
                                          case Beam::Mode::INVALID:
                                                if (cr->type() == Element::Type::CHORD)
                                                      cr->setBeamMode(Beam::Mode::AUTO);
                                                else
                                                      cr->setBeamMode(Beam::Mode::NONE);
                                                break;
                                          }
                                    first = false;
                                    }
                              }
                        }
                  }
            }
      for (MeasureBase* mb = _measures.first(); mb; mb = mb->next()) {
            if (mb->type() == Element::Type::VBOX) {
                  Box* b  = static_cast<Box*>(mb);
                  qreal y = point(styleS(StyleIdx::staffUpperBorder));
                  b->setBottomGap(y);
                  }
            }

      _fileDivision = MScore::division;

      //
      //    sanity check for barLineSpan and update ottavas
      //
      foreach(Staff* staff, _staves) {
            int barLineSpan = staff->barLineSpan();
            int idx = staffIdx(staff);
            int n = nstaves();
            if (idx + barLineSpan > n) {
                  qDebug("bad span: idx %d  span %d staves %d", idx, barLineSpan, n);
                  staff->setBarLineSpan(n - idx);
                  }
            staff->updateOttava();
            }