Palette* MuseScore::newKeySigPalette(bool basic) { Palette* sp = new Palette; sp->setName(QT_TRANSLATE_NOOP("Palette", "Key Signatures")); sp->setMag(1.0); sp->setGrid(56, 64); sp->setYOffset(0.0); for (int i = 0; i < 7; ++i) { KeySig* k = new KeySig(gscore); k->setKey(Key(i + 1)); sp->append(k, qApp->translate("MuseScore", keyNames[i*2])); } for (int i = -7; i < 0; ++i) { KeySig* k = new KeySig(gscore); k->setKey(Key(i)); sp->append(k, qApp->translate("MuseScore", keyNames[(7 + i) * 2 + 1])); } KeySig* k = new KeySig(gscore); k->setKey(Key::C); sp->append(k, qApp->translate("MuseScore", keyNames[14])); if (!basic) { // atonal key signature KeySigEvent nke; nke.setKey(Key::C); nke.setCustom(true); nke.setMode(KeyMode::NONE); KeySig* nk = new KeySig(gscore); nk->setKeySigEvent(nke); sp->append(nk, qApp->translate("MuseScore", keyNames[15])); } return sp; }
KeySigEvent KeyList::key(int tick) const { KeySigEvent ke; ke.setKey(Key::C); if (empty()) return ke; auto i = upper_bound(tick); if (i == begin()) return ke; return (--i)->second; }
void KeySig::changeKeySigEvent(const KeySigEvent& t) { if (_sig == t) return; if (t.custom()) { KeySig* ks = _score->customKeySig(t.customType()); if (!ks) return; keySymbols = ks->keySymbols; } setKeySigEvent(t); }
KeySigEvent KeyList::prevKey(int tick) const { KeySigEvent kc; kc.setKey(Key::C); if (empty()) return kc; auto i = upper_bound(tick); if (i == begin()) return kc; --i; if (i == begin()) return kc; return (--i)->second; }
void KeyList::read(XmlReader& e, Score* cs) { while (e.readNextStartElement()) { if (e.name() == "key") { KeySigEvent ke; int tick = e.intAttribute("tick", 0); if (e.hasAttribute("custom")) ke.setCustomType(e.intAttribute("custom")); else ke.setAccidentalType(e.intAttribute("idx")); (*this)[cs->fileDivision(tick)] = ke; e.readNext(); } else e.unknown(); } }
void KeyList::read(QDomElement e, Score* cs) { for (e = e.firstChildElement(); !e.isNull(); e = e.nextSiblingElement()) { QString tag(e.tagName()); if (tag == "key") { KeySigEvent ke; int tick = e.attribute("tick", "0").toInt(); if (e.hasAttribute("custom")) ke.setCustomType(e.attribute("custom").toInt()); else ke.setAccidentalType(e.attribute("idx").toInt()); (*this)[cs->fileDivision(tick)] = ke; } else domError(e); } }
void AccidentalState::init(const KeySigEvent& keySig, ClefType clef) { if (keySig.custom()) { memset(state, 2, MAX_ACC_STATE); for (const KeySym& s : keySig.keySymbols()) { AccidentalVal a = sym2accidentalVal(s.sym); int line = int(s.spos.y() * 2); int idx = relStep(line, clef) % 7; for (int octave = 0; octave < (11 * 7); octave += 7) { int i = idx + octave ; if (i >= MAX_ACC_STATE) break; state[i] = int(a) + 2; } } } else { init(keySig.key()); } }
void StaffTypeList::read(XmlReader& /*e*/, Score* /*cs*/) { #if 0 while (e.readNextStartElement()) { if (e.name() == "key") { Key k; int tick = e.intAttribute("tick", 0); if (e.hasAttribute("custom")) k = Key::C; // ke.setCustomType(e.intAttribute("custom")); else k = Key(e.intAttribute("idx")); KeySigEvent ke; ke.setKey(k); (*this)[cs->fileDivision(tick)] = ke; e.readNext(); } else e.unknown(); } #endif }
void recognizeMainKeySig(QList<MTrack> &tracks) { bool needToFindKey = false; const auto &opers = preferences.midiImportOperations; const bool isHuman = opers.data()->trackOpers.isHumanPerformance.value(); if (isHuman) needToFindKey = true; if (!needToFindKey) { for (const MTrack &track: tracks) { if (track.mtrack->drumTrack()) continue; if (!track.hasKey) { needToFindKey = true; break; } } } if (!needToFindKey) return; const Key key = findKey(tracks); for (MTrack &track: tracks) { if (track.mtrack->drumTrack()) continue; if (!track.hasKey || isHuman) { KeySigEvent ke; ke.setKey(key); KeyList &staffKeyList = *track.staff->keyList(); staffKeyList[0] = ke; assignKeyListToStaff(staffKeyList, track.staff); } } }
void TestSpanners::spanners04() { MasterScore* score = readScore(DIR + "glissando-cloning01.mscx"); QVERIFY(score); score->doLayout(); // add a linked staff to the existing staff // (copied and adapted from void MuseScore::editInstrList() in mscore/instrdialog.cpp) Staff* oldStaff = score->staff(0); Staff* newStaff = new Staff(score); newStaff->setPart(oldStaff->part()); newStaff->initFromStaffType(oldStaff->staffType()); newStaff->setDefaultClefType(ClefTypeList(ClefType::G)); KeySigEvent ke; ke.setKey(Key::C); newStaff->setKey(0, ke); score->undoInsertStaff(newStaff, 1, false); cloneStaff(oldStaff, newStaff); QVERIFY(saveCompareScore(score, "glissando-cloning01.mscx", DIR + "glissando-cloning01-ref.mscx")); delete score; }
Element* KeySig::drop(const DropData& data) { KeySig* ks = static_cast<KeySig*>(data.element); if (ks->type() != Element::Type::KEYSIG) { delete ks; return 0; } KeySigEvent k = ks->keySigEvent(); if (k.custom() && (score()->customKeySigIdx(ks) == -1)) score()->addCustomKeySig(ks); else delete ks; if (data.modifiers & Qt::ControlModifier) { // apply only to this stave if (k != keySigEvent()) score()->undoChangeKeySig(staff(), tick(), k.key()); } else { // apply to all staves: foreach(Staff* s, score()->rootScore()->staves()) score()->undoChangeKeySig(s, tick(), k.key()); } return this; }
void AccidentalState::init(const KeySigEvent& ks) { int type = ks.accidentalType(); memset(state, 0, 74); for (int octave = 0; octave < 11; ++octave) { if (type > 0) { for (int i = 0; i < type; ++i) { int idx = tpc2step(20 + i) + octave * 7; if (idx < 74) state[idx] = 1; } } else { for (int i = 0; i > type; --i) { int idx = tpc2step(12 + i) + octave * 7; if (idx < 74) state[idx] = -1; } } } }
void MuseScore::editInstrList() { if (cs == 0) return; if (!instrList) instrList = new InstrumentsDialog(this); else if (instrList->isVisible()) { instrList->done(0); return; } instrList->init(); MasterScore* masterScore = cs->masterScore(); instrList->genPartList(masterScore); masterScore->startCmd(); masterScore->deselectAll(); int rv = instrList->exec(); if (rv == 0) { masterScore->endCmd(); return; } ScoreView* csv = currentScoreView(); if (csv && csv->noteEntryMode()) { csv->cmd(getAction("escape")); qApp->processEvents(); updateInputState(csv->score()); } masterScore->inputState().setTrack(-1); // keep the keylist of the first pitched staff to apply it to new ones KeyList tmpKeymap; Staff* firstStaff = 0; for (Staff* s : masterScore->staves()) { KeyList* km = s->keyList(); if (!s->isDrumStaff(Fraction(0,1))) { // TODO tmpKeymap.insert(km->begin(), km->end()); firstStaff = s; break; } } Key normalizedC = Key::C; // normalize the keyevents to concert pitch if necessary if (firstStaff && !masterScore->styleB(Sid::concertPitch) && firstStaff->part()->instrument()->transpose().chromatic ) { int interval = firstStaff->part()->instrument()->transpose().chromatic; normalizedC = transposeKey(normalizedC, interval); for (auto i = tmpKeymap.begin(); i != tmpKeymap.end(); ++i) { int tick = i->first; Key oKey = i->second.key(); tmpKeymap[tick].setKey(transposeKey(oKey, interval)); } } // create initial keyevent for transposing instrument if necessary auto i = tmpKeymap.begin(); if (i == tmpKeymap.end() || i->first != 0) tmpKeymap[0].setKey(normalizedC); // // process modified partitur list // QTreeWidget* pl = instrList->partiturList(); Part* part = 0; int staffIdx = 0; QTreeWidgetItem* item = 0; for (int idx = 0; (item = pl->topLevelItem(idx)); ++idx) { PartListItem* pli = static_cast<PartListItem*>(item); // check if the part contains any remaining staves // mark to remove part if not QTreeWidgetItem* ci = 0; int staves = 0; for (int cidx = 0; (ci = pli->child(cidx)); ++cidx) { StaffListItem* sli = static_cast<StaffListItem*>(ci); if (sli->op() != ListItemOp::I_DELETE) ++staves; } if (staves == 0) pli->op = ListItemOp::I_DELETE; } item = 0; for (int idx = 0; (item = pl->topLevelItem(idx)); ++idx) { int rstaff = 0; PartListItem* pli = static_cast<PartListItem*>(item); if (pli->op == ListItemOp::I_DELETE) masterScore->cmdRemovePart(pli->part); else if (pli->op == ListItemOp::ADD) { const InstrumentTemplate* t = ((PartListItem*)item)->it; part = new Part(masterScore); part->initFromInstrTemplate(t); masterScore->undo(new InsertPart(part, staffIdx)); pli->part = part; QList<Staff*> linked; for (int cidx = 0; pli->child(cidx); ++cidx) { StaffListItem* sli = static_cast<StaffListItem*>(pli->child(cidx)); Staff* staff = new Staff(masterScore); staff->setPart(part); sli->setStaff(staff); staff->init(t, sli->staffType(), cidx); staff->setDefaultClefType(sli->defaultClefType()); if (staffIdx > 0) staff->setBarLineSpan(masterScore->staff(staffIdx - 1)->barLineSpan()); masterScore->undoInsertStaff(staff, cidx); ++staffIdx; Staff* linkedStaff = part->staves()->front(); if (sli->linked() && linkedStaff != staff) { Excerpt::cloneStaff(linkedStaff, staff); linked.append(staff); } } //insert keysigs int sidx = masterScore->staffIdx(part); int eidx = sidx + part->nstaves(); if (firstStaff) masterScore->adjustKeySigs(sidx, eidx, tmpKeymap); } else { part = pli->part; if (part->show() != pli->visible()) part->undoChangeProperty(Pid::VISIBLE, pli->visible()); for (int cidx = 0; pli->child(cidx); ++cidx) { StaffListItem* sli = static_cast<StaffListItem*>(pli->child(cidx)); if (sli->op() == ListItemOp::I_DELETE) { Staff* staff = sli->staff(); int sidx = staff->idx(); masterScore->cmdRemoveStaff(sidx); } else if (sli->op() == ListItemOp::ADD) { Staff* staff = new Staff(masterScore); staff->setPart(part); staff->initFromStaffType(sli->staffType()); sli->setStaff(staff); staff->setDefaultClefType(sli->defaultClefType()); if (staffIdx > 0) staff->setBarLineSpan(masterScore->staff(staffIdx - 1)->barLineSpan()); KeySigEvent ke; if (part->staves()->empty()) ke.setKey(Key::C); else ke = part->staff(0)->keySigEvent(Fraction(0,1)); staff->setKey(Fraction(0,1), ke); Staff* linkedStaff = 0; if (sli->linked()) { if (rstaff > 0) linkedStaff = part->staves()->front(); else { for (Staff* st : *part->staves()) { if (st != staff) { linkedStaff = st; break; } } } } if (linkedStaff) { // do not create a link if linkedStaff will be removed, for (int k = 0; pli->child(k); ++k) { StaffListItem* li = static_cast<StaffListItem*>(pli->child(k)); if (li->op() == ListItemOp::I_DELETE && li->staff() == linkedStaff) { linkedStaff = 0; break; } } } masterScore->undoInsertStaff(staff, rstaff, linkedStaff == 0); if (linkedStaff) Excerpt::cloneStaff(linkedStaff, staff); else { if (firstStaff) masterScore->adjustKeySigs(staffIdx, staffIdx+1, tmpKeymap); } ++staffIdx; ++rstaff; } else if (sli->op() == ListItemOp::UPDATE) { // check changes in staff type Staff* staff = sli->staff(); const StaffType* stfType = sli->staffType(); // use selected staff type if (stfType->name() != staff->staffType(Fraction(0,1))->name()) masterScore->undo(new ChangeStaffType(staff, *stfType)); } else { ++staffIdx; ++rstaff; } } } } // // sort staves // QList<Staff*> dst; for (int idx = 0; idx < pl->topLevelItemCount(); ++idx) { PartListItem* pli = (PartListItem*)pl->topLevelItem(idx); if (pli->op == ListItemOp::I_DELETE) continue; QTreeWidgetItem* ci = 0; for (int cidx = 0; (ci = pli->child(cidx)); ++cidx) { StaffListItem* sli = (StaffListItem*) ci; if (sli->op() == ListItemOp::I_DELETE) continue; dst.push_back(sli->staff()); } } QList<int> dl; int idx2 = 0; bool sort = false; for (Staff* staff : dst) { int idx = masterScore->staves().indexOf(staff); if (idx == -1) qDebug("staff in dialog(%p) not found in score", staff); else dl.push_back(idx); if (idx != idx2) sort = true; ++idx2; } if (sort) masterScore->undo(new SortStaves(masterScore, dl)); // // check for valid barLineSpan and bracketSpan // in all staves // for (Score* s : masterScore->scoreList()) { int n = s->nstaves(); int curSpan = 0; for (int j = 0; j < n; ++j) { Staff* staff = s->staff(j); int span = staff->barLineSpan(); int setSpan = -1; // determine if we need to update barline span if (curSpan == 0) { // no current span; this staff must start a new one if (span == 0) { // no span; this staff must have been within a span // update it to a span of 1 setSpan = j; } else if (span > (n - j)) { // span too big; staves must have been removed // reduce span to last staff setSpan = n - j; } else if (span > 1 && staff->barLineTo() > 0) { // TODO: check if span is still valid // (true if the last staff is the same as it was before this edit) // the code here fixes https://musescore.org/en/node/41786 // but by forcing an update, // we lose custom modifications to staff barLineTo // at least this happens only for span > 1, and not for Mensurstrich (barLineTo<=0) setSpan = span; // force update to pick up new barLineTo value } else { // this staff starts a span curSpan = span; } } else if (span && staff->barLineTo() > 0) { // within a current span; staff must have span of 0 // except for Mensurstrich (barLineTo<=0) // for consistency with Barline::endEdit, // don't special case 1-line staves //TODO s->undoChangeBarLineSpan(staff, 0, 0, (staff->lines() - 1) * 2); } // update barline span if necessary if (setSpan > 0) { // this staff starts a span curSpan = setSpan; // calculate spanFrom and spanTo values // int spanFrom = staff->lines() == 1 ? BARLINE_SPAN_1LINESTAFF_FROM : 0; // int linesTo = masterScore->staff(i + setSpan - 1)->lines(); // int spanTo = linesTo == 1 ? BARLINE_SPAN_1LINESTAFF_TO : (linesTo - 1) * 2; //TODO s->undoChangeBarLineSpan(staff, setSpan, spanFrom, spanTo); } // count off one from barline span --curSpan; // update brackets for (BracketItem* bi : staff->brackets()) { if ((bi->bracketSpan() > (n - j))) bi->undoChangeProperty(Pid::BRACKET_SPAN, n - j); } } } // // there should be at least one measure // if (masterScore->measures()->size() == 0) masterScore->insertMeasure(ElementType::MEASURE, 0, false); const QList<Excerpt*> excerpts(masterScore->excerpts()); // excerpts list may change in the loop below for (Excerpt* excerpt : excerpts) { QList<Staff*> sl = excerpt->partScore()->staves(); QMultiMap<int, int> tr = excerpt->tracks(); if (sl.size() == 0) masterScore->undo(new RemoveExcerpt(excerpt)); else { for (Staff* s : sl) { const LinkedElements* sll = s->links(); for (auto le : *sll) { Staff* ss = toStaff(le); if (ss->primaryStaff()) { for (int j = s->idx() * VOICES; j < (s->idx() + 1) * VOICES; j++) { int strack = tr.key(j, -1); if (strack != -1 && ((strack & ~3) == ss->idx())) break; else if (strack != -1) tr.insert(ss->idx() + strack % VOICES, tr.value(strack, -1)); } } } } } } masterScore->setLayoutAll(); masterScore->endCmd(); masterScore->rebuildAndUpdateExpressive(MuseScore::synthesizer("Fluid")); seq->initInstruments(); }
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; } }
void MTrack::convertTrack(const Fraction &lastTick) { Score* score = staff->score(); int key = 0; // TODO-LIB findKey(mtrack, score->sigmap()); int track = staff->idx() * VOICES; int voices = VOICES; for (int voice = 0; voice < voices; ++voice) { // startChordTick is onTime value of all simultaneous notes // chords here are consist of notes with equal durations // several chords may have the same onTime value Fraction startChordTick; QList<MidiChord> midiChords; for (auto it = chords.begin(); it != chords.end();) { const Fraction &nextChordTick = it->first; const MidiChord& midiChord = it->second; if (midiChord.voice != voice) { ++it; continue; } processPendingNotes(midiChords, voice, startChordTick, nextChordTick); // now 'midiChords' list is empty // so - fill it: // collect all midiChords on current tick position startChordTick = nextChordTick; // debug for (;it != chords.end(); ++it) { const MidiChord& midiChord = it->second; if (it->first != startChordTick) break; if (midiChord.voice != voice) continue; midiChords.append(midiChord); } if (midiChords.isEmpty()) break; } // process last chords at the end of the score processPendingNotes(midiChords, voice, startChordTick, lastTick); } createTuplets(track, score); KeyList* km = staff->keymap(); if (!hasKey && !mtrack->drumTrack()) { KeySigEvent ks; ks.setAccidentalType(key); (*km)[0] = ks; } for (auto it = km->begin(); it != km->end(); ++it) { int tick = it->first; KeySigEvent key = it->second; KeySig* ks = new KeySig(score); ks->setTrack(track); ks->setGenerated(false); ks->setKeySigEvent(key); ks->setMag(staff->mag()); Measure* m = score->tick2measure(tick); Segment* seg = m->getSegment(ks, tick); seg->add(ks); } #if 0 // TODO ClefList* cl = staff->clefList(); for (ciClefEvent i = cl->begin(); i != cl->end(); ++i) { int tick = i.key(); Clef* clef = new Clef(score); clef->setClefType(i.value()); clef->setTrack(track); clef->setGenerated(false); clef->setMag(staff->mag()); Measure* m = score->tick2measure(tick); Segment* seg = m->getSegment(clef, tick); seg->add(clef); } #endif }
void KeySig::setKey(Key key) { KeySigEvent e; e.setKey(key); setKeySigEvent(e); }
void MsScWriter::beginMeasure(const Bww::MeasureBeginFlags mbf) { qDebug() << "MsScWriter::beginMeasure()"; ++measureNumber; // create a new measure currentMeasure = new Measure(score); currentMeasure->setTick(tick); currentMeasure->setTimesig(Fraction(beats, beat)); currentMeasure->setNo(measureNumber); score->measures()->add(currentMeasure); if (mbf.repeatBegin) currentMeasure->setRepeatFlags(RepeatStart); if (mbf.irregular) currentMeasure->setIrregular(true); if (mbf.endingFirst || mbf.endingSecond) { Volta* volta = new Volta(score); volta->setTrack(0); volta->endings().clear(); if (mbf.endingFirst) { volta->setText("1"); volta->endings().append(1); ending = 1; } else { volta->setText("2"); volta->endings().append(2); ending = 2; } volta->setStartElement(currentMeasure); currentMeasure->add(volta); lastVolta = volta; } // set clef, key and time signature in the first measure if (measureNumber == 1) { // clef Clef* clef = new Clef(score); clef->setClefType(CLEF_G); clef->setTrack(0); Segment* s = currentMeasure->getSegment(clef, tick); s->add(clef); // keysig KeySigEvent key; key.setAccidentalType(2); KeySig* keysig = new KeySig(score); keysig->setKeySigEvent(key); keysig->setTrack(0); s = currentMeasure->getSegment(keysig, tick); s->add(keysig); // timesig TimeSig* timesig = new TimeSig(score); timesig->setSig(Fraction(beats, beat)); timesig->setTrack(0); s = currentMeasure->getSegment(timesig, tick); s->add(timesig); } }
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") { KeySig* ks = new KeySig(this); ks->read(e); customKeysigs.append(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 if (s.name() == "Chordname") s.setName("Chord Symbol"); else if (s.name() == "Lyrics odd lines") s.setName("Lyrics Odd Lines"); else if (s.name() == "Lyrics even lines") s.setName("Lyrics Even Lines"); else if (s.name() == "InstrumentsLong") s.setName("Instrument Name (Long)"); else if (s.name() == "InstrumentsShort") s.setName("Instrument Name (Short)"); else if (s.name() == "InstrumentsExcerpt") s.setName("Instrument Name (Part)"); else if (s.name() == "Poet") s.setName("Lyricist"); else if (s.name() == "Technik") s.setName("Technique"); else if (s.name() == "TextLine") s.setName("Text Line"); else if (s.name() == "Tuplets") s.setName("Tuplet"); 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::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; ke.setKey(i->second); KeySig* ks = keySigFactory(ke); if (ks) { 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(); }