Beispiel #1
0
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;
      }
Beispiel #2
0
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);
      }
Beispiel #3
0
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;
            }
      }
Beispiel #4
0
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;
      }
Beispiel #5
0
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;
      }
Beispiel #6
0
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;
      }
Beispiel #7
0
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;
      }
Beispiel #8
0
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;
      }
Beispiel #9
0
int Part::midiPort() const
      {
      return masterScore()->midiPort(instrument()->channel(0)->channel);
      }