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;