Skip to content

Commit

Permalink
Merge pull request #25396 from CMakeScore/parse-dynamics
Browse files Browse the repository at this point in the history
Parse dynamics when finished editing
  • Loading branch information
mathesoncalum authored Dec 30, 2024
2 parents 3ef08b1 + 85e8b12 commit 14d5921
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 15 deletions.
39 changes: 29 additions & 10 deletions src/engraving/dom/dynamic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -423,19 +423,34 @@ void Dynamic::manageBarlineCollisions()
//---------------------------------------------------------

void Dynamic::setDynamicType(const String& tag)
{
const auto dynamicInfo = parseDynamicText(tag);

if (dynamicInfo.first == DynamicType::OTHER) {
LOGD("setDynamicType: other <%s>", muPrintable(tag));
}

setDynamicType(dynamicInfo.first);
setXmlText(dynamicInfo.second);
}

std::pair<DynamicType, String> Dynamic::parseDynamicText(const String& tag) const
{
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;
const std::regex dynamicRegex(R"((?:<sym>.*?</sym>)+|(?:\b)[fmnprsz]+(?:\b(?=[^>]|$)))");
auto begin = std::sregex_iterator(utf8Tag.begin(), utf8Tag.end(), dynamicRegex);
for (auto it = begin; it != std::sregex_iterator(); ++it) {
const std::smatch match = *it;
const 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);
return { DynamicType(i), String::fromStdString(utf8Tag) };
}
}
}
LOGD("setDynamicType: other <%s>", muPrintable(tag));
setDynamicType(DynamicType::OTHER);
setXmlText(tag);
return { DynamicType::OTHER, tag };
}

String Dynamic::dynamicText(DynamicType t)
Expand Down Expand Up @@ -854,7 +869,11 @@ bool Dynamic::setProperty(Pid propertyId, const PropertyValue& v)
{
switch (propertyId) {
case Pid::DYNAMIC_TYPE:
m_dynamicType = v.value<DynamicType>();
if (v.type() == P_TYPE::DYNAMIC_TYPE) {
setDynamicType(v.value<DynamicType>());
break;
}
setDynamicType(v.value<String>());
break;
case Pid::VELOCITY:
m_velocity = v.toInt();
Expand Down
2 changes: 2 additions & 0 deletions src/engraving/dom/dynamic.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ class Dynamic final : public TextBase
void moveSnappedItems(Segment* newSeg, Fraction tickDiff) const;
bool nudge(const EditData& ed);

std::pair<DynamicType, String> parseDynamicText(const String&) const;

DynamicType m_dynamicType = DynamicType::OTHER;
bool m_playDynamic = true;

Expand Down
7 changes: 6 additions & 1 deletion src/engraving/dom/textedit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "mscoreview.h"
#include "navigate.h"
#include "score.h"
#include "dynamic.h"
#include "lyrics.h"

#include "log.h"
Expand Down Expand Up @@ -231,6 +232,10 @@ void TextBase::endEdit(EditData& ed)
// change property to set text to actual value again - this also changes text of linked elements
undoChangeProperty(Pid::TEXT, actualXmlText);

if (isDynamic()) {
undoChangeProperty(Pid::DYNAMIC_TYPE, actualXmlText);
}

renderer()->layoutText1(this);
}

Expand Down Expand Up @@ -711,10 +716,10 @@ bool TextBase::edit(EditData& ed)
}
}
if (!s.isEmpty()) {
deleteSelectedText(ed);
if (currentFormat->fontFamily() == u"ScoreText") {
currentFormat->setFontFamily(propertyDefault(Pid::FONT_FACE).value<String>());
}
deleteSelectedText(ed);
score()->undo(new InsertText(m_cursor, s), &ed);

int startPosition = cursor->currentPosition();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,8 @@
<text>𝅘𝅥 = 100</text>
</Tempo>
<Dynamic>
<subtype>other-dynamics</subtype>
<subtype>f</subtype>
<velocity>96</velocity>
<text><sym>dynamicForte</sym><font face="FreeSerif"/> ma non troppo</text>
</Dynamic>
<Chord>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,8 @@
<text>𝅘𝅥 = 100</text>
</Tempo>
<Dynamic>
<subtype>other-dynamics</subtype>
<subtype>f</subtype>
<velocity>96</velocity>
<text>poco <sym>dynamicForte</sym></text>
</Dynamic>
<Chord>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,8 @@
<text>𝅘𝅥 = 100</text>
</Tempo>
<Dynamic>
<subtype>other-dynamics</subtype>
<subtype>f</subtype>
<velocity>96</velocity>
<text><i></i>moderately <i><sym>dynamicForte</sym></i></text>
</Dynamic>
<Chord>
Expand Down
6 changes: 6 additions & 0 deletions src/engraving/tests/textbase_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,9 @@ TEST_F(Engraving_TextBaseTests, dynamicAddTextBefore)
Dynamic* dynamic = addDynamic(score);
EditData ed;
dynamic->startEdit(ed);
score->startCmd(TranslatableString::untranslatable("Edit dynamic text (test)"));
score->undo(new InsertText(dynamic->cursor(), String(u"poco ")), &ed);
score->endCmd();
dynamic->endEdit(ed);
EXPECT_TRUE(ScoreComp::saveCompareScore(score, u"dynamicAddTextBefore.mscx", TEXTBASE_DATA_DIR + u"dynamicAddTextBefore-ref.mscx"));
}
Expand All @@ -83,8 +85,10 @@ TEST_F(Engraving_TextBaseTests, dynamicAddTextAfter)
EditData ed;
ed.s = String(u" ma non troppo");
dynamic->startEdit(ed);
score->startCmd(TranslatableString::untranslatable("Edit dynamic text (test)"));
dynamic->cursor()->moveCursorToEnd();
dynamic->edit(ed);
score->endCmd();
dynamic->endEdit(ed);
EXPECT_TRUE(ScoreComp::saveCompareScore(score, u"dynamicAddTextAfter.mscx", TEXTBASE_DATA_DIR + u"dynamicAddTextAfter-ref.mscx"));
}
Expand All @@ -95,8 +99,10 @@ TEST_F(Engraving_TextBaseTests, dynamicAddTextNoItalic)
Dynamic* dynamic = addDynamic(score);
EditData ed;
dynamic->startEdit(ed);
score->startCmd(TranslatableString::untranslatable("Edit dynamic text (test)"));
dynamic->setProperty(Pid::FONT_STYLE, PropertyValue::fromValue(0));
score->undo(new InsertText(dynamic->cursor(), String(u"moderately ")), &ed);
score->endCmd();
dynamic->endEdit(ed);
EXPECT_TRUE(ScoreComp::saveCompareScore(score, u"dynamicAddTextNoItalic.mscx", TEXTBASE_DATA_DIR + u"dynamicAddTextNoItalic-ref.mscx"));
}
Expand Down
2 changes: 1 addition & 1 deletion src/notation/view/noteinputbarmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -763,8 +763,8 @@ MenuItemList NoteInputBarModel::makeTextItems()
makeSeparator(),
makeMenuItem("system-text"),
makeMenuItem("staff-text"),
makeMenuItem("expression-text"),
makeMenuItem("dynamics"),
makeMenuItem("expression-text"),
makeMenuItem("rehearsalmark-text"),
makeMenuItem("instrument-change-text"),
makeMenuItem("fingering-text"),
Expand Down

0 comments on commit 14d5921

Please sign in to comment.