diff --git a/importexport/musicxml/importmxmlpass2.cpp b/importexport/musicxml/importmxmlpass2.cpp
index 299339e3a035f..2b6e2dbfc5bbf 100644
--- a/importexport/musicxml/importmxmlpass2.cpp
+++ b/importexport/musicxml/importmxmlpass2.cpp
@@ -41,6 +41,7 @@
#include "libmscore/interval.h"
#include "libmscore/jump.h"
#include "libmscore/keysig.h"
+#include "libmscore/line.h"
#include "libmscore/lyrics.h"
#include "libmscore/marker.h"
#include "libmscore/measure.h"
@@ -3123,6 +3124,7 @@ void MusicXMLParserDirection::handleRepeats(Measure* measure, const int track, c
/**
Parse the /score-partwise/part/measure/direction/direction-type/bracket node.
+ This creates a TextLine for all line-types except "wavy", for which it creates a Trill
*/
void MusicXMLParserDirection::bracket(const QString& type, const int number,
@@ -3130,38 +3132,63 @@ void MusicXMLParserDirection::bracket(const QString& type, const int number,
{
QStringRef lineEnd = _e.attributes().value("line-end");
QStringRef lineType = _e.attributes().value("line-type");
- const auto& spdesc = _pass2.getSpanner({ ElementType::TEXTLINE, number });
+ const bool isWavy = lineType == "wavy";
+ const ElementType elementType = isWavy ? ElementType::TRILL : ElementType::TEXTLINE;
+ const auto& spdesc = _pass2.getSpanner({ elementType, number });
if (type == "start") {
- auto b = spdesc._isStopped ? toTextLine(spdesc._sp) : new TextLine(_score);
- // if (placement == "") placement = "above"; // TODO ? set default
+ SLine* sline = spdesc._isStopped ? spdesc._sp : 0;
+ if ((sline && sline->isTrill()) || (!sline && isWavy)) {
+ if (!sline) sline = new Trill(_score);
+ auto trill = toTrill(sline);
+ trill->setTrillType(Trill::Type::PRALLPRALL_LINE);
+
+ if (!lineEnd.isEmpty() && lineEnd != "none")
+ _logger->logError(QString("line-end not supported for line-type \"wavy\""));
+ }
+ else if ((sline && sline->isTextLine()) || (!sline && !isWavy)) {
+ if (!sline) sline = new TextLine(_score);
+ auto textLine = toTextLine(sline);
+ // if (placement == "") placement = "above"; // TODO ? set default
- b->setBeginHookType(lineEnd != "none" ? HookType::HOOK_90 : HookType::NONE);
- if (lineEnd == "up")
- b->setBeginHookHeight(-1 * b->beginHookHeight());
+ textLine->setBeginHookType(lineEnd != "none" ? HookType::HOOK_90 : HookType::NONE);
+ if (lineEnd == "up")
+ textLine->setBeginHookHeight(-1 * textLine->beginHookHeight());
- // hack: combine with a previous words element
- if (!_wordsText.isEmpty()) {
- // TextLine supports only limited formatting, remove all (compatible with 1.3)
- b->setBeginText(MScoreTextToMXML::toPlainText(_wordsText));
- _wordsText = "";
+ // hack: combine with a previous words element
+ if (!_wordsText.isEmpty()) {
+ // TextLine supports only limited formatting, remove all (compatible with 1.3)
+ textLine->setBeginText(MScoreTextToMXML::toPlainText(_wordsText));
+ _wordsText = "";
+ }
+
+ if (lineType == "solid")
+ textLine->setLineStyle(Qt::SolidLine);
+ else if (lineType == "dashed")
+ textLine->setLineStyle(Qt::DashLine);
+ else if (lineType == "dotted")
+ textLine->setLineStyle(Qt::DotLine);
+ else if (lineType != "wavy")
+ _logger->logError(QString("unsupported line-type: %1").arg(lineType.toString()), &_e);
}
- if (lineType == "solid")
- b->setLineStyle(Qt::SolidLine);
- else if (lineType == "dashed")
- b->setLineStyle(Qt::DashLine);
- else if (lineType == "dotted")
- b->setLineStyle(Qt::DotLine);
- else
- _logger->logError(QString("unsupported line-type: %1").arg(lineType.toString()), &_e);
- starts.append(MusicXmlSpannerDesc(b, ElementType::TEXTLINE, number));
+ starts.append(MusicXmlSpannerDesc(sline, elementType, number));
}
else if (type == "stop") {
- auto b = spdesc._isStarted ? toTextLine(spdesc._sp) : new TextLine(_score);
- b->setEndHookType(lineEnd != "none" ? HookType::HOOK_90 : HookType::NONE);
- if (lineEnd == "up")
- b->setEndHookHeight(-1 * b->endHookHeight());
- stops.append(MusicXmlSpannerDesc(b, ElementType::TEXTLINE, number));
+ SLine* sline = spdesc._isStarted ? spdesc._sp : 0;
+ if ((sline && sline->isTrill()) || (!sline && isWavy)) {
+ if (!sline) sline = new Trill(_score);
+ if (!lineEnd.isEmpty() && lineEnd != "none")
+ _logger->logError(QString("line-end not supported for line-type \"wavy\""));
+ }
+ else if ((sline && sline->isTextLine()) || (!sline && !isWavy)) {
+ if (!sline) sline = new TextLine(_score);
+ auto textLine = toTextLine(sline);
+ textLine->setEndHookType(lineEnd != "none" ? HookType::HOOK_90 : HookType::NONE);
+ if (lineEnd == "up")
+ textLine->setEndHookHeight(-1 * textLine->endHookHeight());
+ }
+
+ stops.append(MusicXmlSpannerDesc(sline, elementType, number));
}
_e.skipCurrentElement();
}
@@ -3393,7 +3420,8 @@ MusicXmlExtendedSpannerDesc& MusicXMLParserPass2::getSpanner(const MusicXmlSpann
return _ottavas[d._nr];
else if (d._tp == ElementType::PEDAL && 0 == d._nr)
return _pedal;
- else if (d._tp == ElementType::TEXTLINE && 0 <= d._nr && d._nr < MAX_NUMBER_LEVEL)
+ else if ((d._tp == ElementType::TEXTLINE || d._tp == ElementType::TRILL)
+ && 0 <= d._nr && d._nr < MAX_NUMBER_LEVEL)
return _brackets[d._nr];
_logger->logError(QString("invalid number %1").arg(d._nr + 1), &_e);
return _dummyNewMusicXmlSpannerDesc;
diff --git a/mtest/musicxml/io/testBracketTypes.pdf b/mtest/musicxml/io/testBracketTypes.pdf
new file mode 100644
index 0000000000000..9cd16e1903fa5
Binary files /dev/null and b/mtest/musicxml/io/testBracketTypes.pdf differ
diff --git a/mtest/musicxml/io/testBracketTypes.xml b/mtest/musicxml/io/testBracketTypes.xml
new file mode 100644
index 0000000000000..085c157208806
--- /dev/null
+++ b/mtest/musicxml/io/testBracketTypes.xml
@@ -0,0 +1,186 @@
+
+
+
+
+ Bracket Types
+
+
+ Henry Ives
+
+ MuseScore 0.7.0
+ 2007-09-10
+
+
+
+
+
+
+
+
+
+ 7
+ 40
+
+
+ 1697.14
+ 1200
+
+ 85.7143
+ 85.7143
+ 85.7143
+ 85.7143
+
+
+ 85.7143
+ 85.7143
+ 85.7143
+ 85.7143
+
+
+
+
+
+
+ title
+ Bracket Types
+
+
+ subtitle
+ MuseScore Testcase
+
+
+ composer
+ Henry Ives
+
+
+
+ brace
+
+
+ Piano
+ Pno.
+
+ Piano
+
+
+
+ 1
+ 1
+ 78.7402
+ 0
+
+
+
+
+
+
+
+
+ 50.00
+ 0.00
+
+ 170.00
+
+
+
+ 1
+
+ 0
+
+
+
+ G
+ 2
+
+
+
+
+
+
+
+
+
+ E
+ 5
+
+ 4
+ 1
+ whole
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ C
+ 5
+
+ 4
+ 1
+ whole
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ A
+ 4
+
+ 4
+ 1
+ whole
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ F
+ 4
+
+ 4
+ 1
+ whole
+
+
+
+
+
+
+
+ light-heavy
+
+
+
+
diff --git a/mtest/musicxml/io/testBracketTypes_ref.mscx b/mtest/musicxml/io/testBracketTypes_ref.mscx
new file mode 100644
index 0000000000000..94c2255ebdaf4
--- /dev/null
+++ b/mtest/musicxml/io/testBracketTypes_ref.mscx
@@ -0,0 +1,262 @@
+
+
+
+
+ 0
+ 480
+
+ 1
+ 1
+ 1
+ 0
+
+ Henry Ives
+
+
+
+
+
+
+
+
+ Bracket Types
+
+
+
+ stdNormal
+
+ 3
+
+ Piano
+
+ Piano
+ Pno.
+ Piano
+ 21
+ 108
+ 21
+ 108
+ keyboard.piano
+ F
+
+ 100
+ 95
+
+
+ 100
+ 33
+
+
+ 100
+ 50
+
+
+ 100
+ 67
+
+
+ 100
+ 100
+
+
+ 120
+ 67
+
+
+ 150
+ 100
+
+
+ 150
+ 50
+
+
+ 120
+ 50
+
+
+ 120
+ 100
+
+
+
+
+
+
+
+
+
+ 12.5
+
+
+
+ Bracket Types
+
+
+
+
+ MuseScore Testcase
+
+
+
+ right,top
+
+ Henry Ives
+
+
+
+
+
+ G
+ G
+
+
+ 4
+ 4
+
+
+
+
+
+
+ 1
+
+
+
+
+ whole
+
+ 76
+ 18
+
+
+
+
+
+
+
+
+
+ -1
+
+
+
+
+
+ 2
+
+
+
+ 1
+
+
+
+
+ whole
+
+ 72
+ 14
+
+
+
+
+
+
+
+
+
+ -1
+
+
+
+
+
+ 3
+
+
+
+ 1
+
+
+
+
+ whole
+
+ 69
+ 17
+
+
+
+
+
+
+
+
+
+ -1
+
+
+
+
+
+ prallprall
+
+
+
+ 1/1
+
+
+
+
+ whole
+
+ 65
+ 13
+
+
+
+ end
+
+
+
+
+ -1/1
+
+
+
+
+
+
+
+
diff --git a/mtest/musicxml/io/tst_mxml_io.cpp b/mtest/musicxml/io/tst_mxml_io.cpp
index df5d9c6607175..177bad1fb015b 100644
--- a/mtest/musicxml/io/tst_mxml_io.cpp
+++ b/mtest/musicxml/io/tst_mxml_io.cpp
@@ -66,6 +66,7 @@ private slots:
void barStyles() { mxmlIoTest("testBarStyles"); }
void barStyles2() { mxmlIoTest("testBarStyles2"); }
void barStyles3() { mxmlIoTest("testBarStyles3"); }
+ void bracketTypes() { mxmlImportTestRef("testBracketTypes"); }
void beamEnd() { mxmlIoTest("testBeamEnd"); }
void beams1() { mxmlIoTest("testBeams1"); }
void beams2() { mxmlIoTest("testBeams2"); }