Skip to content

Commit

Permalink
Fix #307530: MusicXML export for hidden staves
Browse files Browse the repository at this point in the history
  • Loading branch information
HemantAntony committed Jun 27, 2022
1 parent 415d5c0 commit c6dc78c
Show file tree
Hide file tree
Showing 4 changed files with 311 additions and 13 deletions.
12 changes: 8 additions & 4 deletions src/importexport/musicxml/internal/musicxml/exportxml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6645,12 +6645,16 @@ static void writeStaffDetails(XmlWriter& xml, const Part* part)
// currently exported as a two staff part ...
for (size_t i = 0; i < staves; i++) {
Staff* st = part->staff(i);
if (st->lines(Fraction(0, 1)) != 5 || st->isTabStaff(Fraction(0, 1))) {
if (st->lines(Fraction(0, 1)) != 5 || st->isTabStaff(Fraction(0, 1)) || !st->show()) {
XmlWriter::Attributes attributes;
if (staves > 1) {
xml.startElement("staff-details", { { "number", i + 1 } });
} else {
xml.startElement("staff-details");
attributes.push_back({ "number", i + 1 });
}
if (!st->show()) {
attributes.push_back({ "print-object", "no" });
}
xml.startElement("staff-details", attributes);

xml.tag("staff-lines", st->lines(Fraction(0, 1)));
if (st->isTabStaff(Fraction(0, 1)) && instrument->stringData()) {
std::vector<instrString> l = instrument->stringData()->stringList();
Expand Down
36 changes: 27 additions & 9 deletions src/importexport/musicxml/internal/musicxml/importmxmlpass2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1692,21 +1692,22 @@ void MusicXMLParserPass2::part()
_hasDrumset = hasDrumset(instruments);

// set the parts first instrument
setPartInstruments(_logger, &_e, _pass1.getPart(id), id, _score, _pass1.getInstrList(id), _pass1.getIntervals(id), instruments);
Part* part = _pass1.getPart(id);
setPartInstruments(_logger, &_e, part, id, _score, _pass1.getInstrList(id), _pass1.getIntervals(id), instruments);

// set the part name
auto mxmlPart = _pass1.getMusicXmlPart(id);
_pass1.getPart(id)->setPartName(mxmlPart.getName());
part->setPartName(mxmlPart.getName());
if (mxmlPart.getPrintName()) {
_pass1.getPart(id)->setLongName(mxmlPart.getName());
part->setLongName(mxmlPart.getName());
}
if (mxmlPart.getPrintAbbr()) {
_pass1.getPart(id)->setPlainShortName(mxmlPart.getAbbr());
part->setPlainShortName(mxmlPart.getAbbr());
}
// try to prevent an empty track name
if (_pass1.getPart(id)->partName() == "") {
if (part->partName() == "") {
QString instrId = _pass1.getInstrList(id).instrument(Fraction(0, 1));
_pass1.getPart(id)->setPartName(instruments[instrId].name);
part->setPartName(instruments[instrId].name);
}

#ifdef DEBUG_VOICE_MAPPER
Expand Down Expand Up @@ -1738,10 +1739,10 @@ void MusicXMLParserPass2::part()
}

// stop all remaining extends for this part
Measure* lm = _pass1.getPart(id)->score()->lastMeasure();
Measure* lm = part->score()->lastMeasure();
if (lm) {
track_idx_t strack = _pass1.trackForPart(id);
track_idx_t etrack = strack + _pass1.getPart(id)->nstaves() * VOICES;
track_idx_t etrack = strack + part->nstaves() * VOICES;
Fraction lastTick = lm->endTick();
for (track_idx_t trk = strack; trk < etrack; trk++) {
_extendedLyrics.setExtend(-1, trk, lastTick);
Expand Down Expand Up @@ -1777,9 +1778,19 @@ void MusicXMLParserPass2::part()
// set staff type to percussion if incorrectly imported as pitched staff
// Note: part has been read, staff type already set based on clef type and staff-details
// but may be incorrect for a percussion staff that does not use a percussion clef
setStaffTypePercussion(_pass1.getPart(id), drumset);
setStaffTypePercussion(part, drumset);
}

bool showPart = false;
for (Staff* staff : part->staves()) {
if (staff->visible()) {
showPart = true;
break;
}
}

part->setShow(showPart);

addError(checkAtEndElement(_e, "part"));
}

Expand Down Expand Up @@ -2328,6 +2339,13 @@ void MusicXMLParserPass2::staffDetails(const QString& partId)
t->setFrets(25); // sensible default
}

QString visible = _e.attributes().value("print-object").toString();
if (visible == "no") {
_score->staff(staffIdx)->setVisible(false);
} else if (!visible.isEmpty() && visible != "yes") {
_logger->logError(QString("print-object should be \"yes\" or \"no\""));
}

int staffLines = 0;
while (_e.readNextStartElement()) {
if (_e.name() == "staff-lines") {
Expand Down
275 changes: 275 additions & 0 deletions src/importexport/musicxml/tests/data/testHiddenStaves.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,275 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 4.0 Partwise//EN" "http://www.musicxml.org/dtds/partwise.dtd">
<score-partwise version="4.0">
<work>
<work-title>Untitled Score</work-title>
</work>
<identification>
<creator type="composer">Composer / arranger</creator>
<encoding>
<software>MuseScore 0.7.0</software>
<encoding-date>2007-09-10</encoding-date>
<supports element="accidental" type="yes"/>
<supports element="beam" type="yes"/>
<supports element="print" attribute="new-page" type="no"/>
<supports element="print" attribute="new-system" type="no"/>
<supports element="stem" type="yes"/>
</encoding>
</identification>
<part-list>
<part-group type="start" number="1">
<group-symbol>bracket</group-symbol>
</part-group>
<score-part id="P1">
<part-name>Flute</part-name>
<part-abbreviation>Fl.</part-abbreviation>
<score-instrument id="P1-I1">
<instrument-name>Flute</instrument-name>
</score-instrument>
<midi-device id="P1-I1" port="1"></midi-device>
<midi-instrument id="P1-I1">
<midi-channel>1</midi-channel>
<midi-program>74</midi-program>
<volume>78.7402</volume>
<pan>0</pan>
</midi-instrument>
</score-part>
<score-part id="P2">
<part-name>Bassoon</part-name>
<part-abbreviation>Bsn.</part-abbreviation>
<score-instrument id="P2-I1">
<instrument-name>Bassoon</instrument-name>
</score-instrument>
<midi-device id="P2-I1" port="1"></midi-device>
<midi-instrument id="P2-I1">
<midi-channel>2</midi-channel>
<midi-program>71</midi-program>
<volume>78.7402</volume>
<pan>0</pan>
</midi-instrument>
</score-part>
<part-group type="stop" number="1"/>
<score-part id="P3">
<part-name>Harpsichord</part-name>
<part-abbreviation>Hch.</part-abbreviation>
<score-instrument id="P3-I1">
<instrument-name>Harpsichord</instrument-name>
</score-instrument>
<midi-device id="P3-I1" port="1"></midi-device>
<midi-instrument id="P3-I1">
<midi-channel>3</midi-channel>
<midi-program>7</midi-program>
<volume>78.7402</volume>
<pan>0</pan>
</midi-instrument>
</score-part>
<score-part id="P4">
<part-name>Piano</part-name>
<part-abbreviation>Pno.</part-abbreviation>
<score-instrument id="P4-I1">
<instrument-name>Piano</instrument-name>
</score-instrument>
<midi-device id="P4-I1" port="1"></midi-device>
<midi-instrument id="P4-I1">
<midi-channel>4</midi-channel>
<midi-program>1</midi-program>
<volume>78.7402</volume>
<pan>0</pan>
</midi-instrument>
</score-part>
</part-list>
<part id="P1">
<measure number="1">
<attributes>
<divisions>1</divisions>
<key>
<fifths>0</fifths>
</key>
<time>
<beats>4</beats>
<beat-type>4</beat-type>
</time>
<clef>
<sign>G</sign>
<line>2</line>
</clef>
</attributes>
<note>
<rest measure="yes"/>
<duration>4</duration>
<voice>1</voice>
</note>
</measure>
<measure number="2">
<note>
<rest measure="yes"/>
<duration>4</duration>
<voice>1</voice>
</note>
<barline location="right">
<bar-style>light-heavy</bar-style>
</barline>
</measure>
</part>
<part id="P2">
<measure number="1">
<attributes>
<divisions>1</divisions>
<key>
<fifths>0</fifths>
</key>
<time>
<beats>4</beats>
<beat-type>4</beat-type>
</time>
<clef>
<sign>F</sign>
<line>4</line>
</clef>
<staff-details print-object="no">
<staff-lines>5</staff-lines>
</staff-details>
</attributes>
<note>
<rest measure="yes"/>
<duration>4</duration>
<voice>1</voice>
</note>
</measure>
<measure number="2">
<note>
<rest measure="yes"/>
<duration>4</duration>
<voice>1</voice>
</note>
<barline location="right">
<bar-style>light-heavy</bar-style>
</barline>
</measure>
</part>
<part id="P3">
<measure number="1">
<attributes>
<divisions>1</divisions>
<key>
<fifths>0</fifths>
</key>
<time>
<beats>4</beats>
<beat-type>4</beat-type>
</time>
<staves>2</staves>
<clef number="1">
<sign>G</sign>
<line>2</line>
</clef>
<clef number="2">
<sign>F</sign>
<line>4</line>
</clef>
<staff-details number="1" print-object="no">
<staff-lines>5</staff-lines>
</staff-details>
<staff-details number="2" print-object="no">
<staff-lines>5</staff-lines>
</staff-details>
</attributes>
<note>
<rest measure="yes"/>
<duration>4</duration>
<voice>1</voice>
<staff>1</staff>
</note>
<backup>
<duration>4</duration>
</backup>
<note>
<rest measure="yes"/>
<duration>4</duration>
<voice>5</voice>
<staff>2</staff>
</note>
</measure>
<measure number="2">
<note>
<rest measure="yes"/>
<duration>4</duration>
<voice>1</voice>
<staff>1</staff>
</note>
<backup>
<duration>4</duration>
</backup>
<note>
<rest measure="yes"/>
<duration>4</duration>
<voice>5</voice>
<staff>2</staff>
</note>
<barline location="right">
<bar-style>light-heavy</bar-style>
</barline>
</measure>
</part>
<part id="P4">
<measure number="1">
<attributes>
<divisions>1</divisions>
<key>
<fifths>0</fifths>
</key>
<time>
<beats>4</beats>
<beat-type>4</beat-type>
</time>
<staves>2</staves>
<clef number="1">
<sign>G</sign>
<line>2</line>
</clef>
<clef number="2">
<sign>F</sign>
<line>4</line>
</clef>
<staff-details number="2" print-object="no">
<staff-lines>5</staff-lines>
</staff-details>
</attributes>
<note>
<rest measure="yes"/>
<duration>4</duration>
<voice>1</voice>
<staff>1</staff>
</note>
<backup>
<duration>4</duration>
</backup>
<note>
<rest measure="yes"/>
<duration>4</duration>
<voice>5</voice>
<staff>2</staff>
</note>
</measure>
<measure number="2">
<note>
<rest measure="yes"/>
<duration>4</duration>
<voice>1</voice>
<staff>1</staff>
</note>
<backup>
<duration>4</duration>
</backup>
<note>
<rest measure="yes"/>
<duration>4</duration>
<voice>5</voice>
<staff>2</staff>
</note>
<barline location="right">
<bar-style>light-heavy</bar-style>
</barline>
</measure>
</part>
</score-partwise>
1 change: 1 addition & 0 deletions src/importexport/musicxml/tests/tst_mxml_io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ private slots:
void hello() { mxmlIoTest("testHello"); }
void helloReadCompr() { mxmlReadTestCompr("testHello"); }
void helloReadWriteCompr() { mxmlReadWriteTestCompr("testHello"); }
void hiddenStaves() { mxmlIoTest("testHiddenStaves"); }
void implicitMeasure1() { mxmlIoTest("testImplicitMeasure1"); }
void incompleteTuplet() { mxmlIoTestRef("testIncompleteTuplet"); }
void incorrectMidiProgram() { mxmlIoTestRef("testIncorrectMidiProgram"); }
Expand Down

0 comments on commit c6dc78c

Please sign in to comment.