Skip to content

Commit a19ade7

Browse files
rettinghausJojo-Schmitz
authored andcommitted
[MusicXML] invisible notations
Backport of musescore#27422
1 parent 919eccc commit a19ade7

File tree

5 files changed

+376
-106
lines changed

5 files changed

+376
-106
lines changed

importexport/musicxml/exportxml.cpp

+63-62
Original file line numberDiff line numberDiff line change
@@ -188,11 +188,12 @@ void Attributes::stop(XmlWriter& xml)
188188
//---------------------------------------------------------
189189

190190
class Notations {
191-
bool notationsPrinted;
191+
bool notationsPrinted = false;
192+
bool prevElementVisible = true;
192193

193194
public:
194195
Notations() { notationsPrinted = false; }
195-
void tag(XmlWriter& xml);
196+
void tag(XmlWriter& xml, const Element* e);
196197
void etag(XmlWriter& xml);
197198
};
198199

@@ -525,11 +526,20 @@ static QString positioningAttributes(Element const* const el, bool isSpanStart =
525526
// tag
526527
//---------------------------------------------------------
527528

528-
void Notations::tag(XmlWriter& xml)
529+
void Notations::tag(XmlWriter& xml, const Element* e)
529530
{
530-
if (!notationsPrinted)
531-
xml.stag("notations");
531+
if (notationsPrinted && prevElementVisible != e->visible())
532+
etag(xml);
533+
534+
if (!notationsPrinted) {
535+
if (e->visible())
536+
xml.stag("notations");
537+
else
538+
xml.stag("notations print-object=\"no\"");
539+
}
540+
532541
notationsPrinted = true;
542+
prevElementVisible = e->visible();
533543
}
534544

535545
//---------------------------------------------------------
@@ -784,7 +794,7 @@ void SlurHandler::doSlurs(const ChordRest* chordRest, Notations& notations, XmlW
784794
// search for slur(s) starting or stopping at this chord
785795
for (const auto& it : chordRest->score()->spanner()) {
786796
auto sp = it.second;
787-
if (sp->generated() || sp->type() != ElementType::SLUR || !ExportMusicXml::canWrite(sp))
797+
if (sp->generated() || sp->type() != ElementType::SLUR)
788798
continue;
789799
if (chordRest == sp->startElement() || chordRest == sp->endElement()) {
790800
const Slur* s = static_cast<const Slur*>(sp);
@@ -824,7 +834,7 @@ void SlurHandler::doSlurStart(const Slur* s, Notations& notations, XmlWriter& xm
824834
// remove from list and print start
825835
slur[i] = 0;
826836
started[i] = false;
827-
notations.tag(xml);
837+
notations.tag(xml, s);
828838
tagName += QString(" number=\"%1\"").arg(i + 1);
829839
xml.tagE(tagName);
830840
}
@@ -834,7 +844,7 @@ void SlurHandler::doSlurStart(const Slur* s, Notations& notations, XmlWriter& xm
834844
if (i >= 0) {
835845
slur[i] = s;
836846
started[i] = true;
837-
notations.tag(xml);
847+
notations.tag(xml, s);
838848
tagName += QString(" number=\"%1\"").arg(i + 1);
839849
xml.tagE(tagName);
840850
}
@@ -863,7 +873,7 @@ void SlurHandler::doSlurStop(const Slur* s, Notations& notations, XmlWriter& xml
863873
if (i >= 0) {
864874
slur[i] = s;
865875
started[i] = false;
866-
notations.tag(xml);
876+
notations.tag(xml, s);
867877
QString tagName = QString("slur type=\"stop\" number=\"%1\"").arg(i + 1);
868878
tagName += positioningAttributes(s, false);
869879
xml.tagE(tagName);
@@ -875,7 +885,7 @@ void SlurHandler::doSlurStop(const Slur* s, Notations& notations, XmlWriter& xml
875885
// found (already started), stop it and remove from list
876886
slur[i] = 0;
877887
started[i] = false;
878-
notations.tag(xml);
888+
notations.tag(xml, s);
879889
QString tagName = QString("slur type=\"stop\" number=\"%1\"").arg(i + 1);
880890
tagName += positioningAttributes(s, false);
881891
xml.tagE(tagName);
@@ -922,7 +932,7 @@ static void glissando(const Glissando* gli, int number, bool start, Notations& n
922932
tagName += color2xml(gli);
923933
tagName += positioningAttributes(gli, start);
924934
}
925-
notations.tag(xml);
935+
notations.tag(xml, gli);
926936
if (start && gli->showText() && !gli->text().isEmpty())
927937
xml.tag(tagName, gli->text());
928938
else
@@ -1051,7 +1061,7 @@ static void findTrills(const Measure* const measure, int strack, int etrack, Tri
10511061
for (auto it = measure->score()->spanner().lower_bound(stick.ticks()); it != measure->score()->spanner().upper_bound(etick.ticks()); ++it) {
10521062
Element* e = it->second;
10531063
//qDebug("1 trill %p type %d track %d tick %s", e, e->type(), e->track(), qPrintable(e->tick().print()));
1054-
if (e->isTrill() && ExportMusicXml::canWrite(e) && strack <= e->track() && e->track() < etrack
1064+
if (e->isTrill() && strack <= e->track() && e->track() < etrack
10551065
&& e->tick() >= measure->tick() && e->tick() < (measure->tick() + measure->ticks()))
10561066
{
10571067
//qDebug("2 trill %p", e);
@@ -2550,7 +2560,7 @@ static void tupletActualAndNormal(const Tuplet* const t, XmlWriter& xml)
25502560

25512561
static void tupletStart(const Tuplet* const t, const int number, const bool needActualAndNormal, Notations& notations, XmlWriter& xml)
25522562
{
2553-
notations.tag(xml);
2563+
notations.tag(xml, t);
25542564
QString tupletTag = "tuplet type=\"start\"";
25552565
if (!isSimpleTuplet(t))
25562566
tupletTag += QString(" number=\"%1\"").arg(number);
@@ -2581,7 +2591,7 @@ static void tupletStart(const Tuplet* const t, const int number, const bool need
25812591

25822592
static void tupletStop(const Tuplet* const t, const int number, Notations& notations, XmlWriter& xml)
25832593
{
2584-
notations.tag(xml);
2594+
notations.tag(xml, t);
25852595
QString tupletTag = "tuplet type=\"stop\"";
25862596
if (!isSimpleTuplet(t))
25872597
tupletTag += QString(" number=\"%1\"").arg(number);
@@ -2695,7 +2705,7 @@ static void writeDisplayName(XmlWriter& xml, const QString& partName)
26952705

26962706
static void wavyLineStart(const Trill* tr, const int number, Notations& notations, Ornaments& ornaments, XmlWriter& xml)
26972707
{
2698-
notations.tag(xml);
2708+
notations.tag(xml, tr);
26992709
ornaments.tag(xml);
27002710
switch (tr->trillType()) {
27012711
case Trill::Type::TRILL_LINE:
@@ -2725,7 +2735,7 @@ static void wavyLineStart(const Trill* tr, const int number, Notations& notation
27252735

27262736
static void wavyLineStop(const Trill* tr, const int number, Notations& notations, Ornaments& ornaments, XmlWriter& xml)
27272737
{
2728-
notations.tag(xml);
2738+
notations.tag(xml, tr);
27292739
ornaments.tag(xml);
27302740
QString trillXml = QString("wavy-line type=\"stop\" number=\"%1\"").arg(number + 1);
27312741
trillXml += positioningAttributes(tr, false);
@@ -2798,7 +2808,7 @@ void ExportMusicXml::wavyLineStartStop(const ChordRest* const cr, Notations& not
27982808
static void tremoloSingleStartStop(Chord* chord, Notations& notations, Ornaments& ornaments, XmlWriter& xml)
27992809
{
28002810
Tremolo* tr = chord->tremolo();
2801-
if (tr && ExportMusicXml::canWrite(tr)) {
2811+
if (tr) {
28022812
int count = 0;
28032813
TremoloType st = tr->tremoloType();
28042814
QString type;
@@ -2843,7 +2853,7 @@ static void tremoloSingleStartStop(Chord* chord, Notations& notations, Ornaments
28432853

28442854

28452855
if (!type.isEmpty() && ((count > 0 && type != "unmeasured") || (count == 0 && type == "unmeasured"))) {
2846-
notations.tag(xml);
2856+
notations.tag(xml, tr);
28472857
ornaments.tag(xml);
28482858
QString tagName = "tremolo";
28492859
tagName += QString(" type=\"%1\"").arg(type);
@@ -2861,9 +2871,9 @@ static void tremoloSingleStartStop(Chord* chord, Notations& notations, Ornaments
28612871
static void fermatas(const QVector<Element*>& cra, XmlWriter& xml, Notations& notations)
28622872
{
28632873
for (const Element* e : cra) {
2864-
if (!e->isFermata() || !ExportMusicXml::canWrite(e))
2874+
if (!e->isFermata())
28652875
continue;
2866-
notations.tag(xml);
2876+
notations.tag(xml, e);
28672877
fermata(toFermata(e), xml);
28682878
}
28692879
}
@@ -3115,9 +3125,9 @@ static void writeChordLines(const Chord* const chord, XmlWriter& xml, Notations&
31153125
default:
31163126
qDebug("unknown ChordLine subtype %d", int(cl->chordLineType()));
31173127
}
3118-
subtype += color2xml(cl);
31193128
if (!subtype.isEmpty()) {
3120-
notations.tag(xml);
3129+
subtype += color2xml(cl);
3130+
notations.tag(xml, cl);
31213131
articulations.tag(xml);
31223132
xml.tagE(subtype);
31233133
}
@@ -3131,11 +3141,11 @@ static void writeChordLines(const Chord* const chord, XmlWriter& xml, Notations&
31313141

31323142
static void writeBreathMark(const Breath* const breath, XmlWriter& xml, Notations& notations, Articulations& articulations)
31333143
{
3134-
if (breath && ExportMusicXml::canWrite(breath)) {
3144+
if (breath) {
31353145
QString tagName;
31363146
QString type;
31373147

3138-
notations.tag(xml);
3148+
notations.tag(xml, breath);
31393149
articulations.tag(xml);
31403150
if (breath->isCaesura()) {
31413151
tagName = "caesura";
@@ -3214,9 +3224,6 @@ void ExportMusicXml::chordAttributes(Chord* chord, Notations& notations, Technic
32143224
// first the attributes whose elements are children of <articulations>
32153225
Articulations articulations;
32163226
for (const Articulation* a : na) {
3217-
if (!ExportMusicXml::canWrite(a))
3218-
continue;
3219-
32203227
SymId sid = a->symId();
32213228
std::vector<QString> mxmlArtics = symIdToArtics(sid);
32223229

@@ -3237,7 +3244,7 @@ void ExportMusicXml::chordAttributes(Chord* chord, Notations& notations, Technic
32373244
mxmlArtic += color2xml(a);
32383245
mxmlArtic += positioningAttributes(a);
32393246

3240-
notations.tag(_xml);
3247+
notations.tag(_xml, a);
32413248
articulations.tag(_xml);
32423249
_xml.tagE(mxmlArtic);
32433250
}
@@ -3251,8 +3258,6 @@ void ExportMusicXml::chordAttributes(Chord* chord, Notations& notations, Technic
32513258
// then the attributes whose elements are children of <ornaments>
32523259
Ornaments ornaments;
32533260
for (const Articulation* a : na) {
3254-
if (!ExportMusicXml::canWrite(a))
3255-
continue;
32563261
if (!a->isOrnament())
32573262
continue;
32583263

@@ -3266,7 +3271,7 @@ void ExportMusicXml::chordAttributes(Chord* chord, Notations& notations, Technic
32663271
mxmlOrnam += QString(" placement=\"%1\"").arg(placement);
32673272
mxmlOrnam += color2xml(a);
32683273

3269-
notations.tag(_xml);
3274+
notations.tag(_xml, a);
32703275
ornaments.tag(_xml);
32713276
_xml.tagE(mxmlOrnam);
32723277
// accidental-mark is missing
@@ -3279,9 +3284,6 @@ void ExportMusicXml::chordAttributes(Chord* chord, Notations& notations, Technic
32793284

32803285
// and finally the attributes whose elements are children of <technical>
32813286
for (const Articulation* a : na) {
3282-
if (!ExportMusicXml::canWrite(a))
3283-
continue;
3284-
32853287
SymId sid = a->symId();
32863288
QString placement;
32873289
QString direction;
@@ -3303,7 +3305,7 @@ void ExportMusicXml::chordAttributes(Chord* chord, Notations& notations, Technic
33033305

33043306
QString mxmlTechn = symIdToTechn(sid);
33053307
if (!mxmlTechn.isEmpty()) {
3306-
notations.tag(_xml);
3308+
notations.tag(_xml, a);
33073309
technical.tag(_xml);
33083310
mxmlTechn += color2xml(a);
33093311
mxmlTechn += positioningAttributes(a);
@@ -3369,9 +3371,6 @@ void ExportMusicXml::chordAttributes(Chord* chord, Notations& notations, Technic
33693371

33703372
// check if all articulations were handled
33713373
for (const Articulation* a : na) {
3372-
if (!ExportMusicXml::canWrite(a))
3373-
continue;
3374-
33753374
SymId sid = a->symId();
33763375
if (symIdToArtics(sid).empty()
33773376
&& symIdToTechn(sid).isEmpty()
@@ -3411,32 +3410,29 @@ static Arpeggio* findArpeggio(Note* note)
34113410

34123411
static void arpeggiate(Arpeggio* arp, bool front, bool back, XmlWriter& xml, Notations& notations)
34133412
{
3414-
if (!ExportMusicXml::canWrite(arp))
3415-
return;
3416-
34173413
QString tagName;
34183414
switch (arp->arpeggioType()) {
34193415
case ArpeggioType::NORMAL:
3420-
notations.tag(xml);
3416+
notations.tag(xml, arp);
34213417
tagName = "arpeggiate";
34223418
break;
34233419
case ArpeggioType::UP: // fall through
34243420
case ArpeggioType::UP_STRAIGHT: // not supported by MusicXML, export as normal arpeggio
3425-
notations.tag(xml);
3421+
notations.tag(xml, arp);
34263422
tagName = "arpeggiate direction=\"up\"";
34273423
break;
34283424
case ArpeggioType::DOWN: // fall through
34293425
case ArpeggioType::DOWN_STRAIGHT: // not supported by MusicXML, export as normal arpeggio
3430-
notations.tag(xml);
3426+
notations.tag(xml, arp);
34313427
tagName = "arpeggiate direction=\"down\"";
34323428
break;
34333429
case ArpeggioType::BRACKET:
34343430
if (front) {
3435-
notations.tag(xml);
3431+
notations.tag(xml, arp);
34363432
tagName = "non-arpeggiate type=\"bottom\"";
34373433
}
34383434
if (back) {
3439-
notations.tag(xml);
3435+
notations.tag(xml, arp);
34403436
tagName = "non-arpeggiate type=\"top\"";
34413437
}
34423438
break;
@@ -3666,12 +3662,9 @@ static void writeNotehead(XmlWriter& xml, const Note* const note)
36663662
static void writeFingering(XmlWriter& xml, Notations& notations, Technical& technical, const Note* const note)
36673663
{
36683664
for (const Element* e : note->el()) {
3669-
if (!ExportMusicXml::canWrite(e))
3670-
continue;
3671-
36723665
if (e->type() == ElementType::FINGERING) {
36733666
const TextBase* f = toTextBase(e);
3674-
notations.tag(xml);
3667+
notations.tag(xml, e);
36753668
technical.tag(xml);
36763669
QString t = MScoreTextToMXML::toPlainText(f->xmlText());
36773670
QString attr;
@@ -4021,20 +4014,25 @@ void ExportMusicXml::chord(Chord* chord, int staff, const std::vector<Lyrics*>*
40214014
Technical technical;
40224015

40234016
const Tie* tieBack = note->tieBack();
4024-
if (tieBack && ExportMusicXml::canWrite(tieBack)) {
4025-
notations.tag(_xml);
4017+
if (tieBack) {
4018+
notations.tag(_xml, tieBack);
40264019
_xml.tagE("tied type=\"stop\"");
40274020
}
4021+
#if 0 // TODO
4022+
const LaissezVib* laissezVib = note->laissezVib();
4023+
if (laissezVib) {
4024+
notations.tag(_xml, laissezVib);
4025+
#else
4026+
if (hasLaissezVibrer(chord)) {
4027+
#endif
4028+
_xml.tagE("tied type=\"let-ring\"");
4029+
}
40284030
const Tie* tieFor = note->tieFor();
4029-
if (tieFor && ExportMusicXml::canWrite(tieFor)) {
4030-
notations.tag(_xml);
4031+
if (tieFor/* && !laissezVib*/) { // TODO
4032+
notations.tag(_xml, tieFor);
40314033
QString rest = slurTieLineStyle(tieFor);
40324034
_xml.tagE(QString("tied type=\"start\"%1").arg(rest));
40334035
}
4034-
if (hasLaissezVibrer(chord)/* && ExportMusicXml::canWrite(laissezVibrer)*/) {
4035-
notations.tag(_xml);
4036-
_xml.tagE("tied type=\"let-ring\"");
4037-
}
40384036

40394037
if (note == nl.front()) {
40404038
if (!grace)
@@ -4050,7 +4048,7 @@ void ExportMusicXml::chord(Chord* chord, int staff, const std::vector<Lyrics*>*
40504048
// write tablature string / fret
40514049
if (chord->staff() && chord->staff()->isTabStaff(Fraction(0,1)))
40524050
if (note->fret() >= 0 && note->string() >= 0) {
4053-
notations.tag(_xml);
4051+
notations.tag(_xml, note);
40544052
technical.tag(_xml);
40554053
_xml.tag("string", note->string() + 1);
40564054
_xml.tag("fret", note->fret());
@@ -4061,11 +4059,11 @@ void ExportMusicXml::chord(Chord* chord, int staff, const std::vector<Lyrics*>*
40614059
arpeggiate(arp, note == nl.front(), note == nl.back(), _xml, notations);
40624060
}
40634061
for (Spanner* spanner : note->spannerFor())
4064-
if (spanner->type() == ElementType::GLISSANDO && ExportMusicXml::canWrite(spanner)) {
4062+
if (spanner->type() == ElementType::GLISSANDO) {
40654063
gh.doGlissandoStart(static_cast<Glissando*>(spanner), notations, _xml);
40664064
}
40674065
for (Spanner* spanner : note->spannerBack())
4068-
if (spanner->type() == ElementType::GLISSANDO && ExportMusicXml::canWrite(spanner)) {
4066+
if (spanner->type() == ElementType::GLISSANDO) {
40694067
gh.doGlissandoStop(static_cast<Glissando*>(spanner), notations, _xml);
40704068
}
40714069
// write glissando (only for last note)
@@ -5813,6 +5811,9 @@ static void measureStyle(XmlWriter& xml, Attributes& attr, const Measure* const
58135811

58145812
static bool commonAnnotations(ExportMusicXml* exp, const Element* e, int sstaff)
58155813
{
5814+
if (!exp->canWrite(e))
5815+
return false;
5816+
58165817
bool instrChangeHandled = false;
58175818

58185819
// note: the instrument change details are handled in ExportMusicXml::writeMeasureTracks,
@@ -7595,7 +7596,7 @@ void ExportMusicXml::writeMeasure(const Measure* const m,
75957596
writeInstrumentDetails(part->instrument(), _score->styleB(Sid::concertPitch));
75967597
}
75977598
else {
7598-
for (size_t staffIdx : _hiddenStaves) {
7599+
for (int& staffIdx : _hiddenStaves) {
75997600
_attr.doAttr(_xml, true);
76007601
QString attributes;
76017602
if (staves > 1)

0 commit comments

Comments
 (0)