@@ -98,6 +98,7 @@ bool MeiImporter::read(const muse::io::path_t& path)
9898{
9999 m_uids = UIDRegister::instance ();
100100 m_uids->clear ();
101+ m_hasMuseScoreIds = false ;
101102
102103 m_lastMeasure = nullptr ;
103104 m_tremoloId.clear ();
@@ -134,12 +135,30 @@ bool MeiImporter::read(const muse::io::path_t& path)
134135
135136 success = success && this ->readMeiHead (root);
136137
137- success = success && this ->readScore (root);
138-
139138 pugi::xml_attribute xmlId = root.attribute (" xml:id" );
139+ bool hasRootXmlId = false ;
140140 if (xmlId && !String (xmlId.value ()).empty ()) {
141- m_score->setMetaTag (u" xml:id" , String (xmlId.value ()));
142- // Do not keep a xml:id map when having a xml:id seed.
141+ hasRootXmlId = true ;
142+ String xmlIdStr = String (xmlId.value ());
143+ if (xmlIdStr.startsWith (u" mscore-" )) {
144+ // Keep a global flag since we are going to read them only if mei@xml:id is given with mscore EID
145+ m_hasMuseScoreIds = true ;
146+ String valStr = xmlIdStr.remove (u" mscore-" ).replace (' .' , ' /' ).replace (' -' , ' +' );
147+ // The mei@xml:id store the score EID
148+ EID eid = EID::fromStdString (valStr.toStdString ());
149+ if (eid.isValid ()) {
150+ m_score->setEID (eid);
151+ }
152+ } else {
153+ // Keep it as a seed
154+ m_score->setMetaTag (u" xml:id" , xmlIdStr);
155+ }
156+ }
157+
158+ success = success && this ->readScore (root);
159+
160+ if (hasRootXmlId) {
161+ // Do not keep a xml:id map when having a xml:id seed or MscoreIds
143162 m_uids->clear ();
144163 }
145164
@@ -260,7 +279,11 @@ ChordRest* MeiImporter::addChordRest(pugi::xml_node node, Measure* measure, int
260279 } else {
261280 chordRest = Factory::createChord (segment);
262281 }
263- m_uids->reg (chordRest, meiElement.m_xmlId );
282+
283+ // Do not use single note xml:id / EID for the ChordRest
284+ if (!dynamic_cast <const libmei::Note*>(&meiElement)) {
285+ this ->readXmlId (chordRest, meiElement.m_xmlId );
286+ }
264287
265288 if (m_startIdChordRests.count (meiElement.m_xmlId )) {
266289 m_startIdChordRests[meiElement.m_xmlId ] = chordRest;
@@ -458,7 +481,7 @@ EngravingItem* MeiImporter::addAnnotation(const libmei::Element& meiElement, Mea
458481 } else {
459482 return nullptr ;
460483 }
461- m_uids-> reg (item, meiElement.m_xmlId );
484+ this -> readXmlId (item, meiElement.m_xmlId );
462485
463486 item->setTrack (chordRest->track ());
464487 segment->add (item);
@@ -504,7 +527,7 @@ Spanner* MeiImporter::addSpanner(const libmei::Element& meiElement, Measure* mea
504527 } else {
505528 return nullptr ;
506529 }
507- m_uids-> reg (item, meiElement.m_xmlId );
530+ this -> readXmlId (item, meiElement.m_xmlId );
508531
509532 item->setTick (chordRest->tick ());
510533 item->setStartElement (chordRest);
@@ -549,7 +572,7 @@ EngravingItem* MeiImporter::addToChordRest(const libmei::Element& meiElement, Me
549572 } else {
550573 return nullptr ;
551574 }
552- m_uids-> reg (item, meiElement.m_xmlId );
575+ this -> readXmlId (item, meiElement.m_xmlId );
553576
554577 item->setTrack (chordRest->track ());
555578 chordRest->add (item);
@@ -856,6 +879,23 @@ void MeiImporter::setOrnamentAccid(engraving::Ornament* ornament, const Convert:
856879 }
857880}
858881
882+ void MeiImporter::readXmlId (engraving::EngravingItem* item, const std::string& meiUID)
883+ {
884+ String xmlIdStr = String::fromStdString (meiUID);
885+ // We have a file that has MuseScore EIDs and one on this element
886+ if (m_hasMuseScoreIds && xmlIdStr.startsWith (u" mscore-" )) {
887+ String valStr = xmlIdStr.remove (u" mscore-" ).replace (' .' , ' /' ).replace (' -' , ' +' );
888+ EID eid = EID::fromStdString (valStr.toStdString ());
889+ if (!eid.isValid ()) {
890+ Convert::logs.push_back (String (" A valid MuseScore ID could not be extracted from '%1'" ).arg (xmlIdStr));
891+ } else {
892+ item->setEID (eid);
893+ }
894+ } else {
895+ m_uids->reg (item, meiUID);
896+ }
897+ }
898+
859899// ---------------------------------------------------------
860900// parsing methods
861901// ---------------------------------------------------------
@@ -1323,7 +1363,7 @@ bool MeiImporter::readEnding(pugi::xml_node endingNode)
13231363 } else {
13241364 Volta* volta = Factory::createVolta (m_score->dummy ());
13251365 Convert::endingFromMEI (volta, meiEnding, warning);
1326- m_uids-> reg (volta, meiEnding.m_xmlId );
1366+ this -> readXmlId (volta, meiEnding.m_xmlId );
13271367 volta->setTrack (0 );
13281368 volta->setTrack2 (0 );
13291369 volta->setTick (m_endingStart->tick ());
@@ -1356,7 +1396,7 @@ bool MeiImporter::readMeasure(pugi::xml_node measureNode)
13561396 Convert::MeasureStruct measureSt = Convert::measureFromMEI (meiMeasure, warning);
13571397
13581398 Measure* measure = Factory::createMeasure (m_score->dummy ()->system ());
1359- m_uids-> reg (measure, meiMeasure.m_xmlId );
1399+ this -> readXmlId (measure, meiMeasure.m_xmlId );
13601400 measure->setTick (m_ticks);
13611401 measure->setTimesig (m_currentTimeSig);
13621402
@@ -1730,7 +1770,7 @@ bool MeiImporter::readChord(pugi::xml_node chordNode, Measure* measure, int trac
17301770 NOT_SUPPORTED;
17311771 } else {
17321772 TremoloSingleChord* tremolo = Factory::createTremoloSingleChord (chord);
1733- m_uids-> reg (tremolo, m_tremoloId);
1773+ this -> readXmlId (tremolo, m_tremoloId);
17341774 tremolo->setTremoloType (ttype);
17351775 chord->add (tremolo);
17361776 }
@@ -1761,7 +1801,7 @@ bool MeiImporter::readClef(pugi::xml_node clefNode, Measure* measure, int track,
17611801 Segment* segment = measure->getSegment (SegmentType::Clef, ticks + measure->tick ());
17621802 Clef* clef = Factory::createClef (segment);
17631803 Convert::colorFromMEI (clef, meiClef);
1764- m_uids-> reg (clef, meiClef.m_xmlId );
1804+ this -> readXmlId (clef, meiClef.m_xmlId );
17651805 clef->setClefType (ClefTypeList (Convert::clefFromMEI (meiClef, warning)));
17661806 if (warning) {
17671807 this ->addLog (" clef" , clefNode);
@@ -1828,7 +1868,7 @@ bool MeiImporter::readMRest(pugi::xml_node mRestNode, Measure* measure, int trac
18281868 Segment* segment = measure->getSegment (SegmentType::ChordRest, ticks + measure->tick ());
18291869 Rest* rest = Factory::createRest (segment, TDuration (DurationType::V_MEASURE));
18301870 Convert::colorFromMEI (rest, meiMRest);
1831- m_uids-> reg (rest, meiMRest.m_xmlId );
1871+ this -> readXmlId (rest, meiMRest.m_xmlId );
18321872 rest->setTicks (m_currentTimeSig);
18331873 rest->setDurationType (DurationType::V_MEASURE);
18341874 rest->setTrack (track);
@@ -1868,7 +1908,7 @@ bool MeiImporter::readMRpt(pugi::xml_node mRptNode, Measure* measure, int track,
18681908 Segment* segment = measure->getSegment (SegmentType::ChordRest, ticks + measure->tick ());
18691909 MeasureRepeat* measureRepeat = Factory::createMeasureRepeat (segment);
18701910 Convert::colorFromMEI (measureRepeat, meiMRpt);
1871- m_uids-> reg (measureRepeat, meiMRpt.m_xmlId );
1911+ this -> readXmlId (measureRepeat, meiMRpt.m_xmlId );
18721912 measureRepeat->setTrack (track);
18731913 measureRepeat->setTicks (measure->ticks ());
18741914 measureRepeat->setNumMeasures (1 );
@@ -1904,6 +1944,8 @@ bool MeiImporter::readNote(pugi::xml_node noteNode, Measure* measure, int track,
19041944 } else {
19051945 // Support for non MEI-Basic accid and accid.ges encoded in <note> - this is not academic...
19061946 meiAccid.Read (noteNode);
1947+ // Remove the xml:id read from the note in that case
1948+ meiAccid.m_xmlId = " " ;
19071949 }
19081950
19091951 Staff* staff = m_score->staff (track2staff (track));
@@ -1926,7 +1968,7 @@ bool MeiImporter::readNote(pugi::xml_node noteNode, Measure* measure, int track,
19261968 NOT_SUPPORTED;
19271969 } else {
19281970 TremoloSingleChord* tremolo = Factory::createTremoloSingleChord (chord);
1929- m_uids-> reg (tremolo, m_tremoloId);
1971+ this -> readXmlId (tremolo, m_tremoloId);
19301972 tremolo->setTremoloType (ttype);
19311973 chord->add (tremolo);
19321974 }
@@ -1935,7 +1977,7 @@ bool MeiImporter::readNote(pugi::xml_node noteNode, Measure* measure, int track,
19351977
19361978 Note* note = Factory::createNote (chord);
19371979 Convert::colorFromMEI (note, meiNote);
1938- m_uids-> reg (note, meiNote.m_xmlId );
1980+ this -> readXmlId (note, meiNote.m_xmlId );
19391981
19401982 // If there is a reference to the note in the MEI, add it the maps (e.g., for ties)
19411983 if (m_startIdChordRests.count (meiNote.m_xmlId )) {
@@ -1950,7 +1992,7 @@ bool MeiImporter::readNote(pugi::xml_node noteNode, Measure* measure, int track,
19501992
19511993 Accidental* accid = Factory::createAccidental (note);
19521994 Convert::colorFromMEI (accid, meiAccid);
1953- m_uids-> reg (accid, meiAccid.m_xmlId );
1995+ this -> readXmlId (accid, meiAccid.m_xmlId );
19541996 accid->setAccidentalType (pitchSt.accidType );
19551997 // accid->setBracket(AccidentalBracket::BRACKET); // Not supported in MEI-Basic
19561998 accid->setRole (pitchSt.accidRole );
@@ -2046,7 +2088,7 @@ bool MeiImporter::readTuplet(pugi::xml_node tupletNode, Measure* measure, int tr
20462088 meiTuplet.Read (tupletNode);
20472089
20482090 m_tuplet = Factory::createTuplet (measure);
2049- m_uids-> reg (m_tuplet, meiTuplet.m_xmlId );
2091+ this -> readXmlId (m_tuplet, meiTuplet.m_xmlId );
20502092 Convert::tupletFromMEI (m_tuplet, meiTuplet, warning);
20512093 if (warning) {
20522094 this ->addLog (" tuplet" , tupletNode);
@@ -2123,7 +2165,7 @@ bool MeiImporter::readVerse(pugi::xml_node verseNode, Chord* chord)
21232165 }
21242166
21252167 Lyrics* lyrics = Factory::createLyrics (chord);
2126- m_uids-> reg (lyrics, meiVerse.m_xmlId );
2168+ this -> readXmlId (lyrics, meiVerse.m_xmlId );
21272169 Convert::colorFromMEI (lyrics, meiVerse);
21282170
21292171 bool success = true ;
@@ -2402,7 +2444,7 @@ bool MeiImporter::readF(pugi::xml_node fNode, engraving::FiguredBass* figuredBas
24022444
24032445 const int line = static_cast <int >(figuredBass->itemsCount ());
24042446 FiguredBassItem* figuredBassItem = figuredBass->createItem (line);
2405- m_uids-> reg (figuredBassItem, meiF.m_xmlId );
2447+ this -> readXmlId (figuredBassItem, meiF.m_xmlId );
24062448 figuredBassItem->setTrack (figuredBass->track ());
24072449 figuredBassItem->setParent (figuredBass);
24082450
@@ -2444,7 +2486,7 @@ bool MeiImporter::readFb(pugi::xml_node harmNode, Measure* measure)
24442486 return true ;
24452487 }
24462488 // Needs to be registered by hand because we pass meiHarm to MeiImporter::addAnnotation
2447- m_uids-> reg (figuredBass, meiFb.m_xmlId );
2489+ this -> readXmlId (figuredBass, meiFb.m_xmlId );
24482490
24492491 Convert::fbFromMEI (figuredBass, meiHarm, meiFb, warning);
24502492
@@ -2478,7 +2520,7 @@ bool MeiImporter::readFermata(pugi::xml_node fermataNode, Measure* measure)
24782520 if (fermataPos == measure->ticks ()) {
24792521 Segment* segment = measure->getSegment (SegmentType::EndBarLine, measure->tick () + measure->ticks ());
24802522 fermata = Factory::createFermata (segment);
2481- m_uids-> reg (fermata, meiFermata.m_xmlId );
2523+ this -> readXmlId (fermata, meiFermata.m_xmlId );
24822524 const int staffIdx
24832525 = (meiFermata.HasStaff () && meiFermata.GetStaff ().size () > 0 ) ? this ->getStaffIndex (meiFermata.GetStaff ().at (0 )) : 0 ;
24842526 fermata->setTrack (staffIdx * VOICES);
@@ -2791,7 +2833,7 @@ bool MeiImporter::readRepeatMark(pugi::xml_node repeatMarkNode, Measure* measure
27912833 item = Factory::createMarker (measure);
27922834 Convert::markerFromMEI (dynamic_cast <Marker*>(item), meiRepeatMark, warning);
27932835 }
2794- m_uids-> reg (item, meiRepeatMark.m_xmlId );
2836+ this -> readXmlId (item, meiRepeatMark.m_xmlId );
27952837 item->setTrack (0 );
27962838 measure->add (item);
27972839
@@ -2874,7 +2916,7 @@ bool MeiImporter::readTie(pugi::xml_node tieNode, Measure* measure)
28742916 }
28752917
28762918 Tie* tie = new Tie (m_score->dummy ());
2877- m_uids-> reg (tie, meiTie.m_xmlId );
2919+ this -> readXmlId (tie, meiTie.m_xmlId );
28782920 startNote->setTieFor (tie);
28792921 tie->setStartNote (startNote);
28802922 tie->setTrack (startNote->track ());
0 commit comments