From c70a897321f756cf907f5a0031c4876580a616a8 Mon Sep 17 00:00:00 2001 From: CMakeScore <185574671+CMakeScore@users.noreply.github.com> Date: Sat, 9 Nov 2024 22:26:22 +0900 Subject: [PATCH] Parse dynamics when finished editing --- src/engraving/dom/dynamic.cpp | 32 +++++++++++++++++++++++--------- src/engraving/dom/dynamic.h | 2 ++ src/engraving/dom/textedit.cpp | 7 +++++++ 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/src/engraving/dom/dynamic.cpp b/src/engraving/dom/dynamic.cpp index 88f1d83188234..75060773d7fc3 100644 --- a/src/engraving/dom/dynamic.cpp +++ b/src/engraving/dom/dynamic.cpp @@ -423,19 +423,33 @@ void Dynamic::manageBarlineCollisions() //--------------------------------------------------------- void Dynamic::setDynamicType(const String& tag) +{ + const DynamicType dt = parseDynamicText(tag); + + if (dt == DynamicType::OTHER) { + LOGD("setDynamicType: other <%s>", muPrintable(tag)); + } + + setDynamicType(dt); +} + +DynamicType Dynamic::parseDynamicText(const String& tag) { std::string utf8Tag = tag.toStdString(); - size_t n = DYN_LIST.size(); - for (size_t i = 0; i < n; ++i) { - if (TConv::toXml(DynamicType(i)).ascii() == utf8Tag || DYN_LIST[i].text == utf8Tag) { - setDynamicType(DynamicType(i)); - setXmlText(String::fromUtf8(DYN_LIST[i].text)); - return; + std::regex dynamicRegex(R"((?:.*?)+|(?:\b)[fmnprsz]+(?:\b(?=[^>]|$)))"); + for (std::sregex_iterator it(utf8Tag.begin(), utf8Tag.end(), dynamicRegex), end; it != end; ++it) { + std::smatch match = *it; + std::string matchStr = match.str(); + size_t n = DYN_LIST.size(); + for (size_t i = 0; i < n; ++i) { + if (TConv::toXml(DynamicType(i)).ascii() == matchStr || DYN_LIST[i].text == matchStr) { + utf8Tag.replace(match.position(0), match.length(0), DYN_LIST[i].text); + setXmlText(String::fromStdString(utf8Tag)); + return DynamicType(i); + } } } - LOGD("setDynamicType: other <%s>", muPrintable(tag)); - setDynamicType(DynamicType::OTHER); - setXmlText(tag); + return DynamicType::OTHER; } String Dynamic::dynamicText(DynamicType t) diff --git a/src/engraving/dom/dynamic.h b/src/engraving/dom/dynamic.h index 319dece2bb4d6..924b05a6ae9c2 100644 --- a/src/engraving/dom/dynamic.h +++ b/src/engraving/dom/dynamic.h @@ -64,6 +64,8 @@ class Dynamic final : public TextBase void setDynamicType(DynamicType val) { m_dynamicType = val; } void setDynamicType(const String&); + DynamicType parseDynamicText(const String&); + DynamicType dynamicType() const { return m_dynamicType; } int subtype() const override { return static_cast(m_dynamicType); } TranslatableString subtypeUserName() const override; diff --git a/src/engraving/dom/textedit.cpp b/src/engraving/dom/textedit.cpp index 3aa074a09e580..d62511bdf3e05 100644 --- a/src/engraving/dom/textedit.cpp +++ b/src/engraving/dom/textedit.cpp @@ -28,6 +28,7 @@ #include "mscoreview.h" #include "navigate.h" #include "score.h" +#include "dynamic.h" #include "lyrics.h" #include "log.h" @@ -142,6 +143,12 @@ void TextBase::endEdit(EditData& ed) ted->cursor()->endEdit(); + if (isDynamic()) { + Dynamic* d = toDynamic(this); + const DynamicType dt = d->parseDynamicText(xmlText()); + undoChangeProperty(Pid::DYNAMIC_TYPE, dt); + } + UndoStack* undo = score()->undoStack(); IF_ASSERT_FAILED(undo) { return;