diff --git a/mscore/importmxmlpass1.cpp b/mscore/importmxmlpass1.cpp index e81fe059505b0..de51874c64eae 100644 --- a/mscore/importmxmlpass1.cpp +++ b/mscore/importmxmlpass1.cpp @@ -904,6 +904,23 @@ Score::FileError MusicXMLParserPass1::parse() return Score::FileError::FILE_NO_ERROR; } +//--------------------------------------------------------- +// allStaffGroupsIdentical +//--------------------------------------------------------- + +/** + Return true if all staves in Part \a p have the same staff group + */ + +static bool allStaffGroupsIdentical(Part const* const p) + { + for (int i = 1; i < p->nstaves(); ++i) { + if (p->staff(0)->staffGroup() != p->staff(i)->staffGroup()) + return false; + } + return true; + } + //--------------------------------------------------------- // scorePartwise //--------------------------------------------------------- @@ -999,7 +1016,10 @@ void MusicXMLParserPass1::scorePartwise() foreach(Part const* const p, il) { if (p->nstaves() > 1 && !partSet.contains(p)) { p->staff(0)->addBracket(BracketItem(BracketType::BRACE, p->nstaves())); - p->staff(0)->setBarLineSpan(p->nstaves()); + if (allStaffGroupsIdentical(p)) { + // span only if the same types + p->staff(0)->setBarLineSpan(p->nstaves()); + } } } } @@ -2264,22 +2284,22 @@ void MusicXMLParserPass1::staffDetails(const QString& partId) Q_ASSERT(_e.isStartElement() && _e.name() == "staff-details"); logDebugTrace("MusicXMLParserPass1::staffDetails"); + Part* part = getPart(partId); + Q_ASSERT(part); + int staves = part->nstaves(); + QString number = _e.attributes().value("number").toString(); - int n = -1; // invalid + int n = 1; // default if (number != "") { n = number.toInt(); - if (n <= 0) { - logError(QString("invalid number %1").arg(number)); - n = -1; + if (n <= 0 || n > staves) { + logError(QString("invalid staff-details number %1").arg(number)); + n = 1; } - else - n--; // make zero-based } + n--; // make zero-based - Part* part = getPart(partId); - Q_ASSERT(part); - int staves = part->nstaves(); - int staffIdx = _score->staffIdx(part); + int staffIdx = _score->staffIdx(part) + n; StringData* t = 0; if (_score->staff(staffIdx)->isTabStaff()) { @@ -2307,12 +2327,7 @@ void MusicXMLParserPass1::staffDetails(const QString& partId) } if (staffLines > 0) { - if (n == -1) { - for (int i = 0; i < staves; ++i) - setStaffLines(_score, staffIdx+i, staffLines); - } - else - setStaffLines(_score, staffIdx, staffLines); + setStaffLines(_score, staffIdx, staffLines); } if (t) { diff --git a/mscore/importmxmlpass2.cpp b/mscore/importmxmlpass2.cpp index 6e86a31d23dfc..1cebfaadf7fb8 100644 --- a/mscore/importmxmlpass2.cpp +++ b/mscore/importmxmlpass2.cpp @@ -3427,15 +3427,21 @@ void MusicXMLParserPass2::clef(const QString& partId, Measure* measure, const in { Q_ASSERT(_e.isStartElement() && _e.name() == "clef"); + Part* part = _pass1.getPart(partId); + Q_ASSERT(part); + int staves = part->nstaves(); + // TODO: check error handling for // - single staff // - multi-staff with same clef QString strClefno = _e.attributes().value("number").toString(); - int clefno = 1; // reasonable default + int clefno = 1; // default if (strClefno != "") clefno = strClefno.toInt(); - if (clefno <= 0) { - // conversion error (0) or other issue (<0), assume staff 1 + if (clefno <= 0 || clefno > part->nstaves()) { + // conversion error (0) or other issue, assume staff 1 + // Also for Cubase 6.5.5 which generates clef number="2" in a single staff part + // Same fix is required in pass 1 and pass 2 logError(QString("invalid clef number '%1'").arg(strClefno)); clefno = 1; } @@ -3521,27 +3527,21 @@ void MusicXMLParserPass2::clef(const QString& partId, Measure* measure, const in else qDebug("clef: unknown clef ", qPrintable(c), line, i); // TODO - Part* part = _pass1.getPart(partId); - Q_ASSERT(part); - int staves = part->nstaves(); - - if (clefno < staves) { - Clef* clefs = new Clef(_score); - clefs->setClefType(clef); - int track = _pass1.trackForPart(partId) + clefno * VOICES; - clefs->setTrack(track); - Segment* s = measure->getSegment(clefs, tick); - s->add(clefs); - } + Clef* clefs = new Clef(_score); + clefs->setClefType(clef); + int track = _pass1.trackForPart(partId) + clefno * VOICES; + clefs->setTrack(track); + Segment* s = measure->getSegment(clefs, tick); + s->add(clefs); // set the correct staff type // note that this overwrites the staff lines value set in pass 1 // also note that clef handling should probably done in pass1 - int staffIdx = _score->staffIdx(part); + int staffIdx = _score->staffIdx(part) + clefno; int lines = _score->staff(staffIdx)->lines(); if (st == StaffTypes::TAB_DEFAULT || (_hasDrumset && st == StaffTypes::PERC_DEFAULT)) { _score->staff(staffIdx)->setStaffType(StaffType::preset(st)); - _score->staff(staffIdx)->setLines(lines); + _score->staff(staffIdx)->setLines(lines); // preserve previously set staff lines _score->staff(staffIdx)->setBarLineTo((lines - 1) * 2); } } diff --git a/mtest/musicxml/io/testIncorrectStaffNumber_ref.xml b/mtest/musicxml/io/testIncorrectStaffNumber_ref.xml index 5f13fe8651a42..ba66fc53b5e42 100644 --- a/mtest/musicxml/io/testIncorrectStaffNumber_ref.xml +++ b/mtest/musicxml/io/testIncorrectStaffNumber_ref.xml @@ -87,8 +87,8 @@ 4 - G - 2 + F + 4 diff --git a/mtest/musicxml/io/testTablature4.pdf b/mtest/musicxml/io/testTablature4.pdf new file mode 100644 index 0000000000000..eb7275889358a Binary files /dev/null and b/mtest/musicxml/io/testTablature4.pdf differ diff --git a/mtest/musicxml/io/testTablature4.xml b/mtest/musicxml/io/testTablature4.xml new file mode 100644 index 0000000000000..4faacf64297e0 --- /dev/null +++ b/mtest/musicxml/io/testTablature4.xml @@ -0,0 +1,217 @@ + + + + + MuseScore testfile + Tablature 4 + + + Leon Vinken + + MuseScore 0.7.0 + 2007-09-10 + + + + + + + + + + Guitar + Guit. + + Classical Guitar + + + + 1 + 25 + 78.7402 + 0 + + + + Guitar + Guit. + + Classical Guitar [Tablature] + + + + 2 + 25 + 78.7402 + 0 + + + + + + + 1 + + 0 + + + 2 + + G + 2 + -1 + + + TAB + 5 + + + 6 + + E + 2 + + + A + 2 + + + D + 3 + + + G + 3 + + + B + 3 + + + E + 4 + + + + + + G + 3 + + 4 + 1 + whole + 1 + + + 4 + + + + G + 3 + + 4 + 5 + whole + none + 2 + + + 3 + 0 + + + + + light-heavy + + + + + + + 1 + + 0 + + + 2 + + TAB + 5 + + + G + 2 + -1 + + + 6 + + E + 2 + + + A + 2 + + + D + 3 + + + G + 3 + + + B + 3 + + + E + 4 + + + + + + G + 3 + + 4 + 1 + whole + 1 + + + 3 + 0 + + + + + 4 + + + + G + 3 + + 4 + 5 + whole + 2 + + + light-heavy + + + + diff --git a/mtest/musicxml/io/tst_mxml_io.cpp b/mtest/musicxml/io/tst_mxml_io.cpp index 4237dc4a6fdf0..8c720fcd5209d 100644 --- a/mtest/musicxml/io/tst_mxml_io.cpp +++ b/mtest/musicxml/io/tst_mxml_io.cpp @@ -142,6 +142,7 @@ private slots: void tablature1() { mxmlIoTest("testTablature1"); } void tablature2() { mxmlIoTest("testTablature2"); } void tablature3() { mxmlIoTest("testTablature3"); } + void tablature4() { mxmlIoTest("testTablature4"); } void tempo1() { mxmlIoTest("testTempo1"); } void tempo2() { mxmlIoTestRef("testTempo2"); } void timesig1() { mxmlIoTest("testTimesig1"); }