bool Score::saveFile(QIODevice* f, bool msczFormat, bool onlySelection) { if (!MScore::testMode) MScore::testMode = enableTestMode; Xml xml(f); xml.writeOmr = msczFormat; xml.header(); if (!MScore::testMode) { xml.stag("museScore version=\"" MSC_VERSION "\""); xml.tag("programVersion", VERSION); xml.tag("programRevision", revision); } else { xml.stag("museScore version=\"3.00\""); } if (!write(xml, onlySelection)) return false; xml.etag(); if (isMaster()) masterScore()->revisions()->write(xml); if (!onlySelection) { //update version values for i.e. plugin access _mscoreVersion = VERSION; _mscoreRevision = revision.toInt(); _mscVersion = MSCVERSION; } return true; }
bool Score::saveCompressedFile(QFileInfo& info, bool onlySelection) { if (readOnly() && info == *masterScore()->fileInfo()) return false; QFile fp(info.filePath()); if (!fp.open(QIODevice::WriteOnly)) { MScore::lastError = tr("Open File\n%1\nfailed: %2").arg(info.filePath(), strerror(errno)); return false; } return saveCompressedFile(&fp, info, onlySelection); }
void Part::setMidiChannel(int ch, int port, int tick) { Channel* channel = instrument(tick)->channel(0); if (channel->channel == -1) { // Add new mapping MidiMapping mm; mm.part = this; mm.articulation = channel; mm.channel = -1; mm.port = -1; if (ch != -1) mm.channel = ch; if (port != -1) mm.port = port; channel->channel = masterScore()->midiMapping()->size(); masterScore()->midiMapping()->append(mm); } else { // Update existing mapping if (channel->channel >= masterScore()->midiMapping()->size()) { qDebug()<<"Can't' set midi channel: midiMapping is empty!"; return; } if (ch != -1) masterScore()->midiMapping(channel->channel)->channel = ch; if (port != -1) masterScore()->midiMapping(channel->channel)->port = port; masterScore()->midiMapping(channel->channel)->part = this; } }
bool Score::saveFile(QFileInfo& info) { if (readOnly() && info == *masterScore()->fileInfo()) return false; if (info.suffix().isEmpty()) info.setFile(info.filePath() + ".mscx"); QFile fp(info.filePath()); if (!fp.open(QIODevice::WriteOnly)) { MScore::lastError = tr("Open File\n%1\nfailed: %2").arg(info.filePath(), strerror(errno)); return false; } saveFile(&fp, false, false); fp.close(); return true; }
bool Score::saveFile(QIODevice* f, bool msczFormat, bool onlySelection) { XmlWriter xml(this, f); xml.setWriteOmr(msczFormat); xml.header(); if (!MScore::testMode) { xml.stag("museScore version=\"" MSC_VERSION "\""); xml.tag("programVersion", VERSION); xml.tag("programRevision", revision); } else xml.stag("museScore version=\"3.01\""); write(xml, onlySelection); xml.etag(); if (isMaster()) masterScore()->revisions()->write(xml); if (!onlySelection) { //update version values for i.e. plugin access _mscoreVersion = VERSION; _mscoreRevision = revision.toInt(0, 16); _mscVersion = MSCVERSION; } return true; }
bool Score::saveCompressedFile(QIODevice* f, QFileInfo& info, bool onlySelection, bool doCreateThumbnail) { MQZipWriter uz(f); QString fn = info.completeBaseName() + ".mscx"; QBuffer cbuf; cbuf.open(QIODevice::ReadWrite); XmlWriter xml(this, &cbuf); xml << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; xml.stag("container"); xml.stag("rootfiles"); xml.stag(QString("rootfile full-path=\"%1\"").arg(XmlWriter::xmlString(fn))); xml.etag(); for (ImageStoreItem* ip : imageStore) { if (!ip->isUsed(this)) continue; QString path = QString("Pictures/") + ip->hashName(); xml.tag("file", path); } xml.etag(); xml.etag(); cbuf.seek(0); //uz.addDirectory("META-INF"); uz.addFile("META-INF/container.xml", cbuf.data()); // save images //uz.addDirectory("Pictures"); foreach (ImageStoreItem* ip, imageStore) { if (!ip->isUsed(this)) continue; QString path = QString("Pictures/") + ip->hashName(); uz.addFile(path, ip->buffer()); } // create thumbnail if (doCreateThumbnail && !pages().isEmpty()) { QImage pm = createThumbnail(); QByteArray ba; QBuffer b(&ba); if (!b.open(QIODevice::WriteOnly)) qDebug("open buffer failed"); if (!pm.save(&b, "PNG")) qDebug("save failed"); uz.addFile("Thumbnails/thumbnail.png", ba); } #ifdef OMR // // save OMR page images // if (masterScore()->omr()) { int n = masterScore()->omr()->numPages(); for (int i = 0; i < n; ++i) { QString path = QString("OmrPages/page%1.png").arg(i+1); QBuffer cbuf1; OmrPage* page = masterScore()->omr()->page(i); const QImage& image = page->image(); if (!image.save(&cbuf1, "PNG")) { MScore::lastError = tr("save file: cannot save image (%1x%2)").arg(image.width(), image.height()); return false; } uz.addFile(path, cbuf1.data()); cbuf1.close(); } } #endif // // save audio // if (_audio) uz.addFile("audio.ogg", _audio->data()); QBuffer dbuf; dbuf.open(QIODevice::ReadWrite); saveFile(&dbuf, true, onlySelection); dbuf.seek(0); uz.addFile(fn, dbuf.data()); uz.close(); return true; }
QString Page::replaceTextMacros(const QString& s) const { QString d; for (int i = 0, n = s.size(); i < n; ++i) { QChar c = s[i]; if (c == '$' && (i < (n-1))) { QChar c = s[i+1]; switch(c.toLatin1()) { case 'p': // not on first page 1 if (_no) // FALLTHROUGH case 'N': // on page 1 only if there are multiple pages if ( (score()->npages() + score()->pageNumberOffset()) > 1 ) // FALLTHROUGH case 'P': // on all pages { int no = _no + 1 + score()->pageNumberOffset(); if (no > 0 ) d += QString("%1").arg(no); } break; case 'n': d += QString("%1").arg(score()->npages() + score()->pageNumberOffset()); break; case 'i': // not on first page if (_no) // FALLTHROUGH case 'I': d += score()->metaTag("partName").toHtmlEscaped(); break; case 'f': d += masterScore()->fileInfo()->completeBaseName().toHtmlEscaped(); break; case 'F': d += masterScore()->fileInfo()->absoluteFilePath().toHtmlEscaped(); break; case 'd': d += QDate::currentDate().toString(Qt::DefaultLocaleShortDate); break; case 'D': { QString creationDate = score()->metaTag("creationDate"); if (creationDate.isNull()) d += masterScore()->fileInfo()->created().date().toString(Qt::DefaultLocaleShortDate); else d += QDate::fromString(creationDate, Qt::ISODate).toString(Qt::DefaultLocaleShortDate); } break; case 'm': if ( score()->dirty() ) d += QTime::currentTime().toString(Qt::DefaultLocaleShortDate); else d += masterScore()->fileInfo()->lastModified().time().toString(Qt::DefaultLocaleShortDate); break; case 'M': if ( score()->dirty() ) d += QDate::currentDate().toString(Qt::DefaultLocaleShortDate); else d += masterScore()->fileInfo()->lastModified().date().toString(Qt::DefaultLocaleShortDate); break; case 'C': // only on first page if (!_no) // FALLTHROUGH case 'c': d += score()->metaTag("copyright").toHtmlEscaped(); break; case '$': d += '$'; break; case ':': { QString tag; int k = i+2; for (; k < n; ++k) { if (s[k].toLatin1() == ':') break; tag += s[k]; } if (k != n) { // found ':' ? d += score()->metaTag(tag).toHtmlEscaped(); i = k-1; } } break; default: d += '$'; d += c; break; } ++i; } else d += c; } return d; }
bool Score::read(XmlReader& e) { while (e.readNextStartElement()) { e.setTrack(-1); const QStringRef& tag(e.name()); if (tag == "Staff") readStaff(e); else if (tag == "Omr") { #ifdef OMR masterScore()->setOmr(new Omr(this)); masterScore()->omr()->read(e); #else e.skipCurrentElement(); #endif } else if (tag == "Audio") { _audio = new Audio; _audio->read(e); } else if (tag == "showOmr") masterScore()->setShowOmr(e.readInt()); else if (tag == "playMode") _playMode = PlayMode(e.readInt()); else if (tag == "LayerTag") { int id = e.intAttribute("id"); const QString& t = e.attribute("tag"); QString val(e.readElementText()); if (id >= 0 && id < 32) { _layerTags[id] = t; _layerTagComments[id] = val; } } else if (tag == "Layer") { Layer layer; layer.name = e.attribute("name"); layer.tags = e.attribute("mask").toUInt(); _layer.append(layer); e.readNext(); } else if (tag == "currentLayer") _currentLayer = e.readInt(); else if (tag == "Synthesizer") _synthesizerState.read(e); else if (tag == "page-offset") _pageNumberOffset = e.readInt(); else if (tag == "Division") _fileDivision = e.readInt(); else if (tag == "showInvisible") _showInvisible = e.readInt(); else if (tag == "showUnprintable") _showUnprintable = e.readInt(); else if (tag == "showFrames") _showFrames = e.readInt(); else if (tag == "showMargins") _showPageborders = e.readInt(); else if (tag == "Style") { qreal sp = style().value(Sid::spatium).toDouble(); style().load(e); // if (_layoutMode == LayoutMode::FLOAT || _layoutMode == LayoutMode::SYSTEM) { if (_layoutMode == LayoutMode::FLOAT) { // style should not change spatium in // float mode style().set(Sid::spatium, sp); } _scoreFont = ScoreFont::fontFactory(style().value(Sid::MusicalSymbolFont).toString()); } else if (tag == "copyright" || tag == "rights") { Text* text = new Text(this); text->read(e); setMetaTag("copyright", text->xmlText()); 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->read(e); _parts.push_back(part); } else if ((tag == "HairPin") || (tag == "Ottava") || (tag == "TextLine") || (tag == "Volta") || (tag == "Trill") || (tag == "Slur") || (tag == "Pedal")) { Spanner* s = toSpanner(Element::name2Element(tag, this)); s->read(e); addSpanner(s); } else if (tag == "Excerpt") { if (MScore::noExcerpts) e.skipCurrentElement(); else { if (isMaster()) { Excerpt* ex = new Excerpt(static_cast<MasterScore*>(this)); ex->read(e); excerpts().append(ex); } else { qDebug("Score::read(): part cannot have parts"); e.skipCurrentElement(); } } } else if (e.name() == "Tracklist") { int strack = e.intAttribute("sTrack", -1); int dtrack = e.intAttribute("dstTrack", -1); if (strack != -1 && dtrack != -1) e.tracks().insert(strack, dtrack); e.skipCurrentElement(); } else if (tag == "Score") { // recursion if (MScore::noExcerpts) e.skipCurrentElement(); else { e.tracks().clear(); // ??? MasterScore* m = masterScore(); Score* s = new Score(m, MScore::baseStyle()); Excerpt* ex = new Excerpt(m); ex->setPartScore(s); e.setLastMeasure(nullptr); s->read(e); ex->setTracks(e.tracks()); m->addExcerpt(ex); } } else if (tag == "name") { QString n = e.readElementText(); if (!isMaster()) //ignore the name if it's not a child score excerpt()->setTitle(n); } else if (tag == "layoutMode") { QString s = e.readElementText(); if (s == "line") _layoutMode = LayoutMode::LINE; else if (s == "system") _layoutMode = LayoutMode::SYSTEM; else qDebug("layoutMode: %s", qPrintable(s)); } else e.unknown(); } e.reconnectBrokenConnectors(); if (e.error() != QXmlStreamReader::NoError) { qDebug("%s: xml read error at line %lld col %lld: %s", qPrintable(e.getDocName()), e.lineNumber(), e.columnNumber(), e.name().toUtf8().data()); MScore::lastError = QObject::tr("XML read error at line %1, column %2: %3").arg(e.lineNumber()).arg(e.columnNumber()).arg(e.name().toString()); return false; } connectTies(); _fileDivision = MScore::division; #if 0 // TODO:barline // // sanity check for barLineSpan // for (Staff* st : staves()) { int barLineSpan = st->barLineSpan(); int idx = st->idx(); int n = nstaves(); if (idx + barLineSpan > n) { qDebug("bad span: idx %d span %d staves %d", idx, barLineSpan, n); // span until last staff barLineSpan = n - idx; st->setBarLineSpan(barLineSpan); } else if (idx == 0 && barLineSpan == 0) { qDebug("bad span: idx %d span %d staves %d", idx, barLineSpan, n); // span from the first staff until the start of the next span barLineSpan = 1; for (int i = 1; i < n; ++i) { if (staff(i)->barLineSpan() == 0) ++barLineSpan; else break; } st->setBarLineSpan(barLineSpan); } // check spanFrom int minBarLineFrom = st->lines(0) == 1 ? BARLINE_SPAN_1LINESTAFF_FROM : MIN_BARLINE_SPAN_FROMTO; if (st->barLineFrom() < minBarLineFrom) st->setBarLineFrom(minBarLineFrom); if (st->barLineFrom() > st->lines(0) * 2) st->setBarLineFrom(st->lines(0) * 2); // check spanTo Staff* stTo = st->barLineSpan() <= 1 ? st : staff(idx + st->barLineSpan() - 1); // 1-line staves have special bar line spans int maxBarLineTo = stTo->lines(0) == 1 ? BARLINE_SPAN_1LINESTAFF_TO : stTo->lines(0) * 2; if (st->barLineTo() < MIN_BARLINE_SPAN_FROMTO) st->setBarLineTo(MIN_BARLINE_SPAN_FROMTO); if (st->barLineTo() > maxBarLineTo) st->setBarLineTo(maxBarLineTo); // on single staff span, check spanFrom and spanTo are distant enough if (st->barLineSpan() == 1) { if (st->barLineTo() - st->barLineFrom() < MIN_BARLINE_FROMTO_DIST) { st->setBarLineFrom(0); st->setBarLineTo(0); } } } #endif if (!masterScore()->omr()) masterScore()->setShowOmr(false); fixTicks(); masterScore()->rebuildMidiMapping(); masterScore()->updateChannel(); // createPlayEvents(); return true; }
int Part::midiPort() const { return masterScore()->midiPort(instrument()->channel(0)->channel); }