Skip to content

Commit

Permalink
fix #273256, fix #273266: special characters dialog fixes
Browse files Browse the repository at this point in the history
A number of small issues prevent the special characters dialog
from working properly, especially for chord symbols.
Drag and drop only works with some symbols because FSYMBOL was missing
in the switch statements in dragdrop.cpp.
Text elements can handle drop of FSYMBOL (which is why double-click works),
but they weren't getting to chance during drag&drop.
Fix was just adding those case statements.

For Harmony objects, we also needed to add the handlers
in acceptDrop() and drop() (the latter just passing through to TextBase).
However, accidentals require special handling in Harmony::endEdit() in order to parse.
Code was added recently to do this, but it didn't actually work
(I suspect it did when written, but things changed between then and when it was merged).
I rearranged the code in in Harmony::endEdit() a bit - and added comments to explain.
Basically, setHarmony() needs to be called *after* the back-substitution
(replacing flat with "b", sharp with "#"),
but the back-substitution needs to happen after TextBase::endEdit() finalizes the text
(actually, if it were possible to substitute before, that would be better,
but do to the way the undo records are munged in TextBase::endEdit(),
it seemed to dangerous to even try).
Bottom line: I do the TextBase::endEdit(), then the back-substitution,
then the setHarmony().
I needed to be sure to trigger a layout, which required a startCmd/endCmd pair
(since TextBase::endEdit() already called endCmd).
  • Loading branch information
MarcSabatella committed Oct 24, 2019
1 parent b7824c8 commit 563cd5d
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 18 deletions.
80 changes: 62 additions & 18 deletions libmscore/harmony.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -634,17 +634,17 @@ const ChordDescription* Harmony::parseHarmony(const QString& ss, int* root, int*
bool useLiteral = false;
if (ss.endsWith(' '))
useLiteral = true;
QString s = ss.simplified();

if (_harmonyType == HarmonyType::ROMAN) {
_userName = s;
_textName = s;
_userName = ss;
_textName = ss;
*root = Tpc::TPC_INVALID;
*base = Tpc::TPC_INVALID;
return 0;
}

// pre-process for parentheses
QString s = ss.simplified();
if ((_leftParen = s.startsWith('(')))
s.remove(0,1);
if ((_rightParen = (s.endsWith(')') && s.count('(') < s.count(')'))))
Expand Down Expand Up @@ -789,22 +789,50 @@ bool Harmony::edit(EditData& ed)

void Harmony::endEdit(EditData& ed)
{
// render to layout as chord symbol
setHarmony(plainText());
// disable spell check
showSpell = false;
// complete editing: generate xml text, set Pid::TEXT, perform initial layout
// if text has changed, this also triggers setHarmony() which renders chord symbol
// but any rendering or layout performed here is tenative,
// we may still need to substitute special characters,
// and that cannot be until after editing is completed
TextBase::endEdit(ed);

// get plain text
QString s = plainText();

// if user explicitly added symbols to the text,
// convert them back to their respective replacement texts
if (harmonyType() != HarmonyType::ROMAN) {
s.replace("\u1d12b", "bb"); // double-flat
s.replace("\u266d", "b"); // flat
s.replace("\ue260", "b"); // flat
// do not replace natural sign
// (right now adding the symbol explicitly is the only way to force a natural sign to appear at all)
//s.replace("\u266e", "n"); // natural, if one day we support that too
//s.replace("\ue261", "n"); // natural, if one day we support that too
s.replace("\u266f", "#"); // sharp
s.replace("\ue262", "#"); // sharp
s.replace("\u1d12a", "x"); // double-sharp
s.replace("\u0394", "^"); // &Delta;
s.replace("\u00d0", "o"); // &deg;
s.replace("\u00f8", "0"); // &oslash;
s.replace("\u00d8", "0"); // &Oslash;
}
else {
s.replace("\ue260", "\u266d"); // flat
s.replace("\ue261", "\u266e"); // natural
s.replace("\ue262", "\u266f"); // sharp
}

_userName.replace("\u1d12b", "bb"); // double-flat
_userName.replace("\u266d", "b"); // flat
//_userName.replace("\u266e", "n"); // natural, if one day we support that too
_userName.replace("\u266f", "#"); // sharp
_userName.replace("\u1d12a", "x"); // double-sharp
_userName.replace("\u0394", "t"); // &Delta;
_userName.replace("\u00d0", "o"); // &deg;
_userName.replace("\u00f8", "0"); // &oslash;
_userName.replace("\u00d8", "0"); // &Oslash;
// render and layout chord symbol
// (needs to be done here if text hasn't changed, or redone if replacemens were performed above)
score()->startCmd();
setHarmony(s);
layout1();
triggerLayout();
score()->endCmd();

TextBase::endEdit(ed); // layout happens here
// disable spell check
showSpell = false;

if (links()) {
for (ScoreElement* e : *links()) {
Expand Down Expand Up @@ -1731,7 +1759,18 @@ QString Harmony::screenReaderInfo() const

bool Harmony::acceptDrop(EditData& data) const
{
return data.dropElement->isFretDiagram();
Element* e = data.dropElement;
if (e->isFretDiagram()) {
return true;
}
else if (e->isSymbol() || e->isFSymbol()) {
// symbols can be added in edit mode
if (data.getData(this))
return true;
else
return false;
}
return false;
}

//---------------------------------------------------------
Expand All @@ -1747,6 +1786,11 @@ Element* Harmony::drop(EditData& data)
fd->setTrack(track());
score()->undoAddElement(fd);
}
else if (e->isSymbol() || e->isFSymbol()) {
TextBase::drop(data);
layout1();
e = 0; // cannot select
}
else {
qWarning("Harmony: cannot drop <%s>\n", e->name());
delete e;
Expand Down
2 changes: 2 additions & 0 deletions mscore/dragdrop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,7 @@ void ScoreView::dragMoveEvent(QDragMoveEvent* event)
break;
case ElementType::IMAGE:
case ElementType::SYMBOL:
case ElementType::FSYMBOL:
case ElementType::DYNAMIC:
case ElementType::KEYSIG:
case ElementType::CLEF:
Expand Down Expand Up @@ -465,6 +466,7 @@ void ScoreView::dropEvent(QDropEvent* event)
}
break;
case ElementType::SYMBOL:
case ElementType::FSYMBOL:
case ElementType::IMAGE:
applyUserOffset = true;
// fall-thru
Expand Down

0 comments on commit 563cd5d

Please sign in to comment.