@@ -188,11 +188,12 @@ void Attributes::stop(XmlWriter& xml)
188
188
// ---------------------------------------------------------
189
189
190
190
class Notations {
191
- bool notationsPrinted;
191
+ bool notationsPrinted = false ;
192
+ bool prevElementVisible = true ;
192
193
193
194
public:
194
195
Notations () { notationsPrinted = false ; }
195
- void tag (XmlWriter& xml);
196
+ void tag (XmlWriter& xml, const Element* e = nullptr );
196
197
void etag (XmlWriter& xml);
197
198
};
198
199
@@ -525,11 +526,27 @@ static QString positioningAttributes(Element const* const el, bool isSpanStart =
525
526
// tag
526
527
// ---------------------------------------------------------
527
528
528
- void Notations::tag (XmlWriter& xml)
529
+ void Notations::tag (XmlWriter& xml, const Element* e )
529
530
{
530
- if (!notationsPrinted)
531
- xml.stag (" notations" );
531
+ if (!e) {
532
+ if (!notationsPrinted)
533
+ xml.stag (" notations" );
534
+ notationsPrinted = true ;
535
+ return ;
536
+ }
537
+
538
+ if (notationsPrinted && prevElementVisible != e->visible ())
539
+ etag (xml);
540
+
541
+ if (!notationsPrinted) {
542
+ if (e->visible ())
543
+ xml.stag (" notations" );
544
+ else
545
+ xml.stag (" notations print-object=\" no\" " );
546
+ }
547
+
532
548
notationsPrinted = true ;
549
+ prevElementVisible = e->visible ();
533
550
}
534
551
535
552
// ---------------------------------------------------------
@@ -784,7 +801,7 @@ void SlurHandler::doSlurs(const ChordRest* chordRest, Notations& notations, XmlW
784
801
// search for slur(s) starting or stopping at this chord
785
802
for (const auto & it : chordRest->score ()->spanner ()) {
786
803
auto sp = it.second ;
787
- if (sp->generated () || sp->type () != ElementType::SLUR || ! ExportMusicXml::canWrite (sp) )
804
+ if (sp->generated () || sp->type () != ElementType::SLUR)
788
805
continue ;
789
806
if (chordRest == sp->startElement () || chordRest == sp->endElement ()) {
790
807
const Slur* s = static_cast <const Slur*>(sp);
@@ -824,7 +841,7 @@ void SlurHandler::doSlurStart(const Slur* s, Notations& notations, XmlWriter& xm
824
841
// remove from list and print start
825
842
slur[i] = 0 ;
826
843
started[i] = false ;
827
- notations.tag (xml);
844
+ notations.tag (xml, s );
828
845
tagName += QString (" number=\" %1\" " ).arg (i + 1 );
829
846
xml.tagE (tagName);
830
847
}
@@ -834,7 +851,7 @@ void SlurHandler::doSlurStart(const Slur* s, Notations& notations, XmlWriter& xm
834
851
if (i >= 0 ) {
835
852
slur[i] = s;
836
853
started[i] = true ;
837
- notations.tag (xml);
854
+ notations.tag (xml, s );
838
855
tagName += QString (" number=\" %1\" " ).arg (i + 1 );
839
856
xml.tagE (tagName);
840
857
}
@@ -863,7 +880,7 @@ void SlurHandler::doSlurStop(const Slur* s, Notations& notations, XmlWriter& xml
863
880
if (i >= 0 ) {
864
881
slur[i] = s;
865
882
started[i] = false ;
866
- notations.tag (xml);
883
+ notations.tag (xml, s );
867
884
QString tagName = QString (" slur type=\" stop\" number=\" %1\" " ).arg (i + 1 );
868
885
tagName += positioningAttributes (s, false );
869
886
xml.tagE (tagName);
@@ -875,7 +892,7 @@ void SlurHandler::doSlurStop(const Slur* s, Notations& notations, XmlWriter& xml
875
892
// found (already started), stop it and remove from list
876
893
slur[i] = 0 ;
877
894
started[i] = false ;
878
- notations.tag (xml);
895
+ notations.tag (xml, s );
879
896
QString tagName = QString (" slur type=\" stop\" number=\" %1\" " ).arg (i + 1 );
880
897
tagName += positioningAttributes (s, false );
881
898
xml.tagE (tagName);
@@ -922,7 +939,7 @@ static void glissando(const Glissando* gli, int number, bool start, Notations& n
922
939
tagName += color2xml (gli);
923
940
tagName += positioningAttributes (gli, start);
924
941
}
925
- notations.tag (xml);
942
+ notations.tag (xml, gli );
926
943
if (start && gli->showText () && !gli->text ().isEmpty ())
927
944
xml.tag (tagName, gli->text ());
928
945
else
@@ -1051,7 +1068,7 @@ static void findTrills(const Measure* const measure, int strack, int etrack, Tri
1051
1068
for (auto it = measure->score ()->spanner ().lower_bound (stick.ticks ()); it != measure->score ()->spanner ().upper_bound (etick.ticks ()); ++it) {
1052
1069
Element* e = it->second ;
1053
1070
// 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
1071
+ if (e->isTrill () && strack <= e->track () && e->track () < etrack
1055
1072
&& e->tick () >= measure->tick () && e->tick () < (measure->tick () + measure->ticks ()))
1056
1073
{
1057
1074
// qDebug("2 trill %p", e);
@@ -2550,7 +2567,7 @@ static void tupletActualAndNormal(const Tuplet* const t, XmlWriter& xml)
2550
2567
2551
2568
static void tupletStart (const Tuplet* const t, const int number, const bool needActualAndNormal, Notations& notations, XmlWriter& xml)
2552
2569
{
2553
- notations.tag (xml);
2570
+ notations.tag (xml, t );
2554
2571
QString tupletTag = " tuplet type=\" start\" " ;
2555
2572
if (!isSimpleTuplet (t))
2556
2573
tupletTag += QString (" number=\" %1\" " ).arg (number);
@@ -2581,7 +2598,7 @@ static void tupletStart(const Tuplet* const t, const int number, const bool need
2581
2598
2582
2599
static void tupletStop (const Tuplet* const t, const int number, Notations& notations, XmlWriter& xml)
2583
2600
{
2584
- notations.tag (xml);
2601
+ notations.tag (xml, t );
2585
2602
QString tupletTag = " tuplet type=\" stop\" " ;
2586
2603
if (!isSimpleTuplet (t))
2587
2604
tupletTag += QString (" number=\" %1\" " ).arg (number);
@@ -2695,7 +2712,7 @@ static void writeDisplayName(XmlWriter& xml, const QString& partName)
2695
2712
2696
2713
static void wavyLineStart (const Trill* tr, const int number, Notations& notations, Ornaments& ornaments, XmlWriter& xml)
2697
2714
{
2698
- notations.tag (xml);
2715
+ notations.tag (xml, tr );
2699
2716
ornaments.tag (xml);
2700
2717
switch (tr->trillType ()) {
2701
2718
case Trill::Type::TRILL_LINE:
@@ -2725,7 +2742,7 @@ static void wavyLineStart(const Trill* tr, const int number, Notations& notation
2725
2742
2726
2743
static void wavyLineStop (const Trill* tr, const int number, Notations& notations, Ornaments& ornaments, XmlWriter& xml)
2727
2744
{
2728
- notations.tag (xml);
2745
+ notations.tag (xml, tr );
2729
2746
ornaments.tag (xml);
2730
2747
QString trillXml = QString (" wavy-line type=\" stop\" number=\" %1\" " ).arg (number + 1 );
2731
2748
trillXml += positioningAttributes (tr, false );
@@ -2798,7 +2815,7 @@ void ExportMusicXml::wavyLineStartStop(const ChordRest* const cr, Notations& not
2798
2815
static void tremoloSingleStartStop (Chord* chord, Notations& notations, Ornaments& ornaments, XmlWriter& xml)
2799
2816
{
2800
2817
Tremolo* tr = chord->tremolo ();
2801
- if (tr && ExportMusicXml::canWrite (tr) ) {
2818
+ if (tr) {
2802
2819
int count = 0 ;
2803
2820
TremoloType st = tr->tremoloType ();
2804
2821
QString type;
@@ -2843,7 +2860,7 @@ static void tremoloSingleStartStop(Chord* chord, Notations& notations, Ornaments
2843
2860
2844
2861
2845
2862
if (!type.isEmpty () && ((count > 0 && type != " unmeasured" ) || (count == 0 && type == " unmeasured" ))) {
2846
- notations.tag (xml);
2863
+ notations.tag (xml, tr );
2847
2864
ornaments.tag (xml);
2848
2865
QString tagName = " tremolo" ;
2849
2866
tagName += QString (" type=\" %1\" " ).arg (type);
@@ -2861,9 +2878,9 @@ static void tremoloSingleStartStop(Chord* chord, Notations& notations, Ornaments
2861
2878
static void fermatas (const QVector<Element*>& cra, XmlWriter& xml, Notations& notations)
2862
2879
{
2863
2880
for (const Element* e : cra) {
2864
- if (!e->isFermata () || ! ExportMusicXml::canWrite (e) )
2881
+ if (!e->isFermata ())
2865
2882
continue ;
2866
- notations.tag (xml);
2883
+ notations.tag (xml, e );
2867
2884
fermata (toFermata (e), xml);
2868
2885
}
2869
2886
}
@@ -3115,9 +3132,9 @@ static void writeChordLines(const Chord* const chord, XmlWriter& xml, Notations&
3115
3132
default :
3116
3133
qDebug (" unknown ChordLine subtype %d" , int (cl->chordLineType ()));
3117
3134
}
3118
- subtype += color2xml (cl);
3119
3135
if (!subtype.isEmpty ()) {
3120
- notations.tag (xml);
3136
+ subtype += color2xml (cl);
3137
+ notations.tag (xml, cl);
3121
3138
articulations.tag (xml);
3122
3139
xml.tagE (subtype);
3123
3140
}
@@ -3131,11 +3148,11 @@ static void writeChordLines(const Chord* const chord, XmlWriter& xml, Notations&
3131
3148
3132
3149
static void writeBreathMark (const Breath* const breath, XmlWriter& xml, Notations& notations, Articulations& articulations)
3133
3150
{
3134
- if (breath && ExportMusicXml::canWrite (breath) ) {
3151
+ if (breath) {
3135
3152
QString tagName;
3136
3153
QString type;
3137
3154
3138
- notations.tag (xml);
3155
+ notations.tag (xml, breath );
3139
3156
articulations.tag (xml);
3140
3157
if (breath->isCaesura ()) {
3141
3158
tagName = " caesura" ;
@@ -3214,9 +3231,6 @@ void ExportMusicXml::chordAttributes(Chord* chord, Notations& notations, Technic
3214
3231
// first the attributes whose elements are children of <articulations>
3215
3232
Articulations articulations;
3216
3233
for (const Articulation* a : na) {
3217
- if (!ExportMusicXml::canWrite (a))
3218
- continue ;
3219
-
3220
3234
SymId sid = a->symId ();
3221
3235
std::vector<QString> mxmlArtics = symIdToArtics (sid);
3222
3236
@@ -3237,7 +3251,7 @@ void ExportMusicXml::chordAttributes(Chord* chord, Notations& notations, Technic
3237
3251
mxmlArtic += color2xml (a);
3238
3252
mxmlArtic += positioningAttributes (a);
3239
3253
3240
- notations.tag (_xml);
3254
+ notations.tag (_xml, a );
3241
3255
articulations.tag (_xml);
3242
3256
_xml.tagE (mxmlArtic);
3243
3257
}
@@ -3251,8 +3265,6 @@ void ExportMusicXml::chordAttributes(Chord* chord, Notations& notations, Technic
3251
3265
// then the attributes whose elements are children of <ornaments>
3252
3266
Ornaments ornaments;
3253
3267
for (const Articulation* a : na) {
3254
- if (!ExportMusicXml::canWrite (a))
3255
- continue ;
3256
3268
if (!a->isOrnament ())
3257
3269
continue ;
3258
3270
@@ -3266,7 +3278,7 @@ void ExportMusicXml::chordAttributes(Chord* chord, Notations& notations, Technic
3266
3278
mxmlOrnam += QString (" placement=\" %1\" " ).arg (placement);
3267
3279
mxmlOrnam += color2xml (a);
3268
3280
3269
- notations.tag (_xml);
3281
+ notations.tag (_xml, a );
3270
3282
ornaments.tag (_xml);
3271
3283
_xml.tagE (mxmlOrnam);
3272
3284
// accidental-mark is missing
@@ -3279,9 +3291,6 @@ void ExportMusicXml::chordAttributes(Chord* chord, Notations& notations, Technic
3279
3291
3280
3292
// and finally the attributes whose elements are children of <technical>
3281
3293
for (const Articulation* a : na) {
3282
- if (!ExportMusicXml::canWrite (a))
3283
- continue ;
3284
-
3285
3294
SymId sid = a->symId ();
3286
3295
QString placement;
3287
3296
QString direction;
@@ -3303,7 +3312,7 @@ void ExportMusicXml::chordAttributes(Chord* chord, Notations& notations, Technic
3303
3312
3304
3313
QString mxmlTechn = symIdToTechn (sid);
3305
3314
if (!mxmlTechn.isEmpty ()) {
3306
- notations.tag (_xml);
3315
+ notations.tag (_xml, a );
3307
3316
technical.tag (_xml);
3308
3317
mxmlTechn += color2xml (a);
3309
3318
mxmlTechn += positioningAttributes (a);
@@ -3369,9 +3378,6 @@ void ExportMusicXml::chordAttributes(Chord* chord, Notations& notations, Technic
3369
3378
3370
3379
// check if all articulations were handled
3371
3380
for (const Articulation* a : na) {
3372
- if (!ExportMusicXml::canWrite (a))
3373
- continue ;
3374
-
3375
3381
SymId sid = a->symId ();
3376
3382
if (symIdToArtics (sid).empty ()
3377
3383
&& symIdToTechn (sid).isEmpty ()
@@ -3411,32 +3417,29 @@ static Arpeggio* findArpeggio(Note* note)
3411
3417
3412
3418
static void arpeggiate (Arpeggio* arp, bool front, bool back, XmlWriter& xml, Notations& notations)
3413
3419
{
3414
- if (!ExportMusicXml::canWrite (arp))
3415
- return ;
3416
-
3417
3420
QString tagName;
3418
3421
switch (arp->arpeggioType ()) {
3419
3422
case ArpeggioType::NORMAL:
3420
- notations.tag (xml);
3423
+ notations.tag (xml, arp );
3421
3424
tagName = " arpeggiate" ;
3422
3425
break ;
3423
3426
case ArpeggioType::UP: // fall through
3424
3427
case ArpeggioType::UP_STRAIGHT: // not supported by MusicXML, export as normal arpeggio
3425
- notations.tag (xml);
3428
+ notations.tag (xml, arp );
3426
3429
tagName = " arpeggiate direction=\" up\" " ;
3427
3430
break ;
3428
3431
case ArpeggioType::DOWN: // fall through
3429
3432
case ArpeggioType::DOWN_STRAIGHT: // not supported by MusicXML, export as normal arpeggio
3430
- notations.tag (xml);
3433
+ notations.tag (xml, arp );
3431
3434
tagName = " arpeggiate direction=\" down\" " ;
3432
3435
break ;
3433
3436
case ArpeggioType::BRACKET:
3434
3437
if (front) {
3435
- notations.tag (xml);
3438
+ notations.tag (xml, arp );
3436
3439
tagName = " non-arpeggiate type=\" bottom\" " ;
3437
3440
}
3438
3441
if (back) {
3439
- notations.tag (xml);
3442
+ notations.tag (xml, arp );
3440
3443
tagName = " non-arpeggiate type=\" top\" " ;
3441
3444
}
3442
3445
break ;
@@ -3666,12 +3669,9 @@ static void writeNotehead(XmlWriter& xml, const Note* const note)
3666
3669
static void writeFingering (XmlWriter& xml, Notations& notations, Technical& technical, const Note* const note)
3667
3670
{
3668
3671
for (const Element* e : note->el ()) {
3669
- if (!ExportMusicXml::canWrite (e))
3670
- continue ;
3671
-
3672
3672
if (e->type () == ElementType::FINGERING) {
3673
3673
const TextBase* f = toTextBase (e);
3674
- notations.tag (xml);
3674
+ notations.tag (xml, e );
3675
3675
technical.tag (xml);
3676
3676
QString t = MScoreTextToMXML::toPlainText (f->xmlText ());
3677
3677
QString attr;
@@ -4021,20 +4021,30 @@ void ExportMusicXml::chord(Chord* chord, int staff, const std::vector<Lyrics*>*
4021
4021
Technical technical;
4022
4022
4023
4023
const Tie* tieBack = note->tieBack ();
4024
- if (tieBack && ExportMusicXml::canWrite (tieBack) ) {
4025
- notations.tag (_xml);
4024
+ if (tieBack) {
4025
+ notations.tag (_xml, tieBack );
4026
4026
_xml.tagE (" tied type=\" stop\" " );
4027
4027
}
4028
+ #if 0 // TODO
4029
+ const LaissezVib* laissezVib = note->laissezVib();
4030
+ if (laissezVib) {
4031
+ notations.tag(_xml, laissezVib);
4032
+ _xml.tagE(QString("tied type=\"let-ring\"%1").arg(rest));
4033
+ }
4028
4034
const Tie* tieFor = note->tieFor();
4029
- if (tieFor && ExportMusicXml::canWrite (tieFor)) {
4035
+ if (tieFor/* && !laissezVib*/) {
4036
+ #else
4037
+ if (hasLaissezVibrer (chord)) {
4030
4038
notations.tag (_xml);
4039
+ _xml.tagE (" tied type=\" let-ring\" " );
4040
+ }
4041
+ const Tie* tieFor = note->tieFor ();
4042
+ if (tieFor) {
4043
+ #endif
4044
+ notations.tag (_xml, tieFor);
4031
4045
QString rest = slurTieLineStyle (tieFor);
4032
4046
_xml.tagE (QString (" tied type=\" start\" %1" ).arg (rest));
4033
4047
}
4034
- if (hasLaissezVibrer (chord)/* && ExportMusicXml::canWrite(laissezVibrer)*/ ) {
4035
- notations.tag (_xml);
4036
- _xml.tagE (" tied type=\" let-ring\" " );
4037
- }
4038
4048
4039
4049
if (note == nl.front ()) {
4040
4050
if (!grace)
@@ -4050,7 +4060,7 @@ void ExportMusicXml::chord(Chord* chord, int staff, const std::vector<Lyrics*>*
4050
4060
// write tablature string / fret
4051
4061
if (chord->staff () && chord->staff ()->isTabStaff (Fraction (0 ,1 )))
4052
4062
if (note->fret () >= 0 && note->string () >= 0 ) {
4053
- notations.tag (_xml);
4063
+ notations.tag (_xml, note );
4054
4064
technical.tag (_xml);
4055
4065
_xml.tag (" string" , note->string () + 1 );
4056
4066
_xml.tag (" fret" , note->fret ());
@@ -4061,11 +4071,11 @@ void ExportMusicXml::chord(Chord* chord, int staff, const std::vector<Lyrics*>*
4061
4071
arpeggiate (arp, note == nl.front (), note == nl.back (), _xml, notations);
4062
4072
}
4063
4073
for (Spanner* spanner : note->spannerFor ())
4064
- if (spanner->type () == ElementType::GLISSANDO && ExportMusicXml::canWrite (spanner) ) {
4074
+ if (spanner->type () == ElementType::GLISSANDO) {
4065
4075
gh.doGlissandoStart (static_cast <Glissando*>(spanner), notations, _xml);
4066
4076
}
4067
4077
for (Spanner* spanner : note->spannerBack ())
4068
- if (spanner->type () == ElementType::GLISSANDO && ExportMusicXml::canWrite (spanner) ) {
4078
+ if (spanner->type () == ElementType::GLISSANDO) {
4069
4079
gh.doGlissandoStop (static_cast <Glissando*>(spanner), notations, _xml);
4070
4080
}
4071
4081
// write glissando (only for last note)
@@ -5813,6 +5823,9 @@ static void measureStyle(XmlWriter& xml, Attributes& attr, const Measure* const
5813
5823
5814
5824
static bool commonAnnotations (ExportMusicXml* exp , const Element* e, int sstaff)
5815
5825
{
5826
+ if (!exp ->canWrite (e))
5827
+ return false ;
5828
+
5816
5829
bool instrChangeHandled = false ;
5817
5830
5818
5831
// note: the instrument change details are handled in ExportMusicXml::writeMeasureTracks,
@@ -7595,7 +7608,7 @@ void ExportMusicXml::writeMeasure(const Measure* const m,
7595
7608
writeInstrumentDetails (part->instrument (), _score->styleB (Sid::concertPitch));
7596
7609
}
7597
7610
else {
7598
- for (size_t staffIdx : _hiddenStaves) {
7611
+ for (int & staffIdx : _hiddenStaves) {
7599
7612
_attr.doAttr (_xml, true );
7600
7613
QString attributes;
7601
7614
if (staves > 1 )
0 commit comments