diff --git a/src/engraving/libmscore/factory.cpp b/src/engraving/libmscore/factory.cpp index 4631e31c43dc..b26994439060 100644 --- a/src/engraving/libmscore/factory.cpp +++ b/src/engraving/libmscore/factory.cpp @@ -712,3 +712,5 @@ PlayTechAnnotation* Factory::createPlayTechAnnotation(Segment * parent, PlayingT return annotation; } + +CREATE_ITEM_IMPL(Capo, ElementType::CAPO, Segment, isAccessibleEnabled) diff --git a/src/engraving/libmscore/factory.h b/src/engraving/libmscore/factory.h index 349b32e96c09..9a76c18b27a9 100644 --- a/src/engraving/libmscore/factory.h +++ b/src/engraving/libmscore/factory.h @@ -268,6 +268,8 @@ class Factory static PlayTechAnnotation* createPlayTechAnnotation(Segment* parent, PlayingTechniqueType techniqueType, TextStyleType styleType, bool isAccessibleEnabled = true); + static Capo* createCapo(Segment* parent, bool isAccessibleEnabled = true); + private: static EngravingItem* doCreateItem(ElementType type, EngravingItem* parent); }; diff --git a/src/engraving/rw/compat/compatutils.cpp b/src/engraving/rw/compat/compatutils.cpp index 078dfeda7abd..ca2282546bf4 100644 --- a/src/engraving/rw/compat/compatutils.cpp +++ b/src/engraving/rw/compat/compatutils.cpp @@ -40,6 +40,7 @@ #include "libmscore/stafftext.h" #include "libmscore/stafftextbase.h" #include "libmscore/playtechannotation.h" +#include "libmscore/capo.h" #include "types/string.h" @@ -74,6 +75,8 @@ const std::set CompatUtils::ORNAMENT_IDS { void CompatUtils::doCompatibilityConversions(MasterScore* masterScore) { + TRACEFUNC; + if (!masterScore) { return; } @@ -90,6 +93,7 @@ void CompatUtils::doCompatibilityConversions(MasterScore* masterScore) splitArticulations(masterScore); resetArticulationOffsets(masterScore); resetStemLengthsForTwoNoteTrems(masterScore); + replaceStaffTextWithCapo(masterScore); } } @@ -560,3 +564,65 @@ void CompatUtils::resetStemLengthsForTwoNoteTrems(MasterScore* masterScore) } } } + +void CompatUtils::replaceStaffTextWithCapo(MasterScore* score) +{ + TRACEFUNC; + + std::set oldCapoSet; + + for (Measure* measure = score->firstMeasure(); measure; measure = measure->nextMeasure()) { + for (Segment* segment = measure->first(); segment; segment = segment->next()) { + for (EngravingItem* annotation : segment->annotations()) { + if (!annotation || !annotation->isStaffTextBase()) { + continue; + } + + StaffTextBase* text = toStaffTextBase(annotation); + + if (text->capo() > 0) { + oldCapoSet.insert(text); + } else { + continue; + } + + LinkedObjects* links = text->links(); + if (!links || links->empty()) { + continue; + } + + for (EngravingObject* linked : *links) { + if (linked != text && linked && linked->isStaffTextBase()) { + oldCapoSet.insert(toStaffTextBase(linked)); + } + } + } + } + } + + for (StaffTextBase* oldCapo : oldCapoSet) { + Segment* parentSegment = oldCapo->segment(); + Capo* newCapo = Factory::createCapo(parentSegment); + + int capoFretPosition = oldCapo->capo() - 1; + + CapoParams params; + params.active = capoFretPosition > 0; + params.fretPosition = capoFretPosition; + + newCapo->setTrack(oldCapo->track()); + newCapo->setParams(params); + newCapo->setProperty(Pid::PLACEMENT, oldCapo->placement()); + + LinkedObjects* links = oldCapo->links(); + newCapo->setLinks(links); + if (links) { + links->push_back(newCapo); + } + + parentSegment->add(newCapo); + parentSegment->removeAnnotation(oldCapo); + + delete oldCapo; + } +} diff --git a/src/engraving/rw/compat/compatutils.h b/src/engraving/rw/compat/compatutils.h index 055c00395ef2..540341c57977 100644 --- a/src/engraving/rw/compat/compatutils.h +++ b/src/engraving/rw/compat/compatutils.h @@ -55,6 +55,7 @@ class CompatUtils static void resetRestVerticalOffset(MasterScore* masterScore); static void resetArticulationOffsets(MasterScore* masterScore); static void resetStemLengthsForTwoNoteTrems(MasterScore* masterScore); + static void replaceStaffTextWithCapo(MasterScore* masterScore); }; } #endif // MU_ENGRAVING_COMPATUTILS_H