diff --git a/src/importexport/musicxml/internal/import/importmusicxmlpass2.cpp b/src/importexport/musicxml/internal/import/importmusicxmlpass2.cpp index b13fbbe51e1d7..a2b68f5993b98 100644 --- a/src/importexport/musicxml/internal/import/importmusicxmlpass2.cpp +++ b/src/importexport/musicxml/internal/import/importmusicxmlpass2.cpp @@ -4644,26 +4644,27 @@ static String countSegno(const String& plainWords) void MusicXmlParserDirection::handleRepeats(Measure* measure, const Fraction tick, bool& measureHasCoda, SegnoStack& segnos, DelayedDirectionsList& delayedDirections) { - if (!configuration()->inferTextType()) { - return; - } // Try to recognize the various repeats + // The explicit repeat attributes of the element are always honoured; + // only the purely text-based fallback depends on the inferTextType preference String repeat; const String plainWords = MScoreTextToMusicXml::toPlainText(m_wordsText.toLower().simplified()); + const String wordsRepeat = matchRepeat(plainWords); if (!m_sndCoda.empty()) { repeat = u"coda"; } else if (!m_sndDacapo.empty()) { - repeat = u"daCapo"; + // the accompanying words may refine the jump type (e.g. "D.C. al Fine") + repeat = wordsRepeat.startsWith(u"daCapo") ? wordsRepeat : u"daCapo"; } else if (!m_sndDalsegno.empty()) { - repeat = u"dalSegno"; + repeat = wordsRepeat.startsWith(u"dalSegno") ? wordsRepeat : u"dalSegno"; } else if (!m_sndFine.empty()) { repeat = u"fine"; } else if (!m_sndSegno.empty()) { repeat = u"segno"; } else if (!m_sndToCoda.empty()) { repeat = u"toCoda"; - } else { - repeat = matchRepeat(plainWords); + } else if (configuration()->inferTextType()) { + repeat = wordsRepeat; } // Check if repeat number has become detached if (repeat == u"coda" || repeat == u"segno") { diff --git a/src/importexport/musicxml/tests/data/testDCalCoda_ref.xml b/src/importexport/musicxml/tests/data/testDCalCoda_ref.xml new file mode 100644 index 0000000000000..2209e6fe166bf --- /dev/null +++ b/src/importexport/musicxml/tests/data/testDCalCoda_ref.xml @@ -0,0 +1,145 @@ + + + + + MuseScore testfile + D.C. al Coda + + + Leon Vinken + + MuseScore 0.7.0 + 2007-09-10 + + + + + + + + + + Guitar + + Guitar + + + + 1 + 1 + 78.7402 + 0 + + + + + + + 1 + + 0 + + + + G + 2 + -1 + + + + + G + 3 + + 4 + 1 + whole + + + + + + A + 3 + + 4 + 1 + whole + + + + To Coda + coda + + + + + + + + B + 3 + + 4 + 1 + whole + + + + + + C + 4 + + 4 + 1 + whole + + + + + + 100 + + + + + + + + + + + D + 4 + + 4 + 1 + whole + + + + + + E + 4 + + 4 + 1 + whole + + + + D.C. al Coda + + + + + light-heavy + + + + diff --git a/src/importexport/musicxml/tests/data/testDSalCodaMisplaced_ref.mscx b/src/importexport/musicxml/tests/data/testDSalCodaMisplaced_ref.mscx index 1c84cd381457b..fe596da9789e0 100644 --- a/src/importexport/musicxml/tests/data/testDSalCodaMisplaced_ref.mscx +++ b/src/importexport/musicxml/tests/data/testDSalCodaMisplaced_ref.mscx @@ -400,8 +400,8 @@ D.S. al Coda segno - end - + coda + codab diff --git a/src/importexport/musicxml/tests/data/testDSalCoda_ref.mscx b/src/importexport/musicxml/tests/data/testDSalCoda_ref.mscx index 1c84cd381457b..fe596da9789e0 100644 --- a/src/importexport/musicxml/tests/data/testDSalCoda_ref.mscx +++ b/src/importexport/musicxml/tests/data/testDSalCoda_ref.mscx @@ -400,8 +400,8 @@ D.S. al Coda segno - end - + coda + codab diff --git a/src/importexport/musicxml/tests/musicxml_tests.cpp b/src/importexport/musicxml/tests/musicxml_tests.cpp index cc47ad7cde8db..b1f1e21e4360f 100644 --- a/src/importexport/musicxml/tests/musicxml_tests.cpp +++ b/src/importexport/musicxml/tests/musicxml_tests.cpp @@ -23,6 +23,8 @@ #include #include "engraving/engravingerrors.h" +#include "engraving/dom/jump.h" +#include "engraving/dom/marker.h" #include "engraving/dom/masterscore.h" #include "settings.h" @@ -520,11 +522,42 @@ TEST_F(MusicXml_Tests, dalSegno) { musicXmlIoTest("testDalSegno"); } TEST_F(MusicXml_Tests, dcalCoda) { - musicXmlIoTest("testDCalCoda"); + // "D.C. al Coda" with imports as a D.C. al Coda jump, + // so the exported attribute becomes linked to the coda marker + musicXmlIoTestRef("testDCalCoda"); } TEST_F(MusicXml_Tests, dcalFine) { musicXmlIoTest("testDCalFine"); } +TEST_F(MusicXml_Tests, dcalFineNoInferTextType) { + // Explicit and attributes must be + // imported as Jump/Marker elements even when text type inference is disabled + MScore::debugMode = true; + + setValue(PREF_IMPORT_MUSICXML_INFERTEXT, Val(false)); + + MasterScore* score = readScore(XML_IO_DATA_DIR + u"testDCalFine.xml"); + ASSERT_TRUE(score); + + const Jump* jump = nullptr; + const Marker* marker = nullptr; + for (const MeasureBase* mb = score->first(); mb; mb = mb->next()) { + for (const EngravingItem* el : mb->el()) { + if (el->isJump()) { + jump = toJump(el); + } else if (el->isMarker()) { + marker = toMarker(el); + } + } + } + + ASSERT_TRUE(jump); + EXPECT_EQ(jump->jumpType(), JumpType::DC_AL_FINE); + ASSERT_TRUE(marker); + EXPECT_EQ(marker->markerType(), MarkerType::FINE); + + delete score; +} TEST_F(MusicXml_Tests, directions1) { musicXmlIoTestRef("testDirections1"); }