@@ -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 );
196
197
void etag (XmlWriter& xml);
197
198
};
198
199
@@ -525,11 +526,20 @@ 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 (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
+
532
541
notationsPrinted = true ;
542
+ prevElementVisible = e->visible ();
533
543
}
534
544
535
545
// ---------------------------------------------------------
@@ -784,7 +794,7 @@ void SlurHandler::doSlurs(const ChordRest* chordRest, Notations& notations, XmlW
784
794
// search for slur(s) starting or stopping at this chord
785
795
for (const auto & it : chordRest->score ()->spanner ()) {
786
796
auto sp = it.second ;
787
- if (sp->generated () || sp->type () != ElementType::SLUR || ! ExportMusicXml::canWrite (sp) )
797
+ if (sp->generated () || sp->type () != ElementType::SLUR)
788
798
continue ;
789
799
if (chordRest == sp->startElement () || chordRest == sp->endElement ()) {
790
800
const Slur* s = static_cast <const Slur*>(sp);
@@ -824,7 +834,7 @@ void SlurHandler::doSlurStart(const Slur* s, Notations& notations, XmlWriter& xm
824
834
// remove from list and print start
825
835
slur[i] = 0 ;
826
836
started[i] = false ;
827
- notations.tag (xml);
837
+ notations.tag (xml, s );
828
838
tagName += QString (" number=\" %1\" " ).arg (i + 1 );
829
839
xml.tagE (tagName);
830
840
}
@@ -834,7 +844,7 @@ void SlurHandler::doSlurStart(const Slur* s, Notations& notations, XmlWriter& xm
834
844
if (i >= 0 ) {
835
845
slur[i] = s;
836
846
started[i] = true ;
837
- notations.tag (xml);
847
+ notations.tag (xml, s );
838
848
tagName += QString (" number=\" %1\" " ).arg (i + 1 );
839
849
xml.tagE (tagName);
840
850
}
@@ -863,7 +873,7 @@ void SlurHandler::doSlurStop(const Slur* s, Notations& notations, XmlWriter& xml
863
873
if (i >= 0 ) {
864
874
slur[i] = s;
865
875
started[i] = false ;
866
- notations.tag (xml);
876
+ notations.tag (xml, s );
867
877
QString tagName = QString (" slur type=\" stop\" number=\" %1\" " ).arg (i + 1 );
868
878
tagName += positioningAttributes (s, false );
869
879
xml.tagE (tagName);
@@ -875,7 +885,7 @@ void SlurHandler::doSlurStop(const Slur* s, Notations& notations, XmlWriter& xml
875
885
// found (already started), stop it and remove from list
876
886
slur[i] = 0 ;
877
887
started[i] = false ;
878
- notations.tag (xml);
888
+ notations.tag (xml, s );
879
889
QString tagName = QString (" slur type=\" stop\" number=\" %1\" " ).arg (i + 1 );
880
890
tagName += positioningAttributes (s, false );
881
891
xml.tagE (tagName);
@@ -922,7 +932,7 @@ static void glissando(const Glissando* gli, int number, bool start, Notations& n
922
932
tagName += color2xml (gli);
923
933
tagName += positioningAttributes (gli, start);
924
934
}
925
- notations.tag (xml);
935
+ notations.tag (xml, gli );
926
936
if (start && gli->showText () && !gli->text ().isEmpty ())
927
937
xml.tag (tagName, gli->text ());
928
938
else
@@ -1051,7 +1061,7 @@ static void findTrills(const Measure* const measure, int strack, int etrack, Tri
1051
1061
for (auto it = measure->score ()->spanner ().lower_bound (stick.ticks ()); it != measure->score ()->spanner ().upper_bound (etick.ticks ()); ++it) {
1052
1062
Element* e = it->second ;
1053
1063
// 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
1055
1065
&& e->tick () >= measure->tick () && e->tick () < (measure->tick () + measure->ticks ()))
1056
1066
{
1057
1067
// qDebug("2 trill %p", e);
@@ -2550,7 +2560,7 @@ static void tupletActualAndNormal(const Tuplet* const t, XmlWriter& xml)
2550
2560
2551
2561
static void tupletStart (const Tuplet* const t, const int number, const bool needActualAndNormal, Notations& notations, XmlWriter& xml)
2552
2562
{
2553
- notations.tag (xml);
2563
+ notations.tag (xml, t );
2554
2564
QString tupletTag = " tuplet type=\" start\" " ;
2555
2565
if (!isSimpleTuplet (t))
2556
2566
tupletTag += QString (" number=\" %1\" " ).arg (number);
@@ -2581,7 +2591,7 @@ static void tupletStart(const Tuplet* const t, const int number, const bool need
2581
2591
2582
2592
static void tupletStop (const Tuplet* const t, const int number, Notations& notations, XmlWriter& xml)
2583
2593
{
2584
- notations.tag (xml);
2594
+ notations.tag (xml, t );
2585
2595
QString tupletTag = " tuplet type=\" stop\" " ;
2586
2596
if (!isSimpleTuplet (t))
2587
2597
tupletTag += QString (" number=\" %1\" " ).arg (number);
@@ -2695,7 +2705,7 @@ static void writeDisplayName(XmlWriter& xml, const QString& partName)
2695
2705
2696
2706
static void wavyLineStart (const Trill* tr, const int number, Notations& notations, Ornaments& ornaments, XmlWriter& xml)
2697
2707
{
2698
- notations.tag (xml);
2708
+ notations.tag (xml, tr );
2699
2709
ornaments.tag (xml);
2700
2710
switch (tr->trillType ()) {
2701
2711
case Trill::Type::TRILL_LINE:
@@ -2725,7 +2735,7 @@ static void wavyLineStart(const Trill* tr, const int number, Notations& notation
2725
2735
2726
2736
static void wavyLineStop (const Trill* tr, const int number, Notations& notations, Ornaments& ornaments, XmlWriter& xml)
2727
2737
{
2728
- notations.tag (xml);
2738
+ notations.tag (xml, tr );
2729
2739
ornaments.tag (xml);
2730
2740
QString trillXml = QString (" wavy-line type=\" stop\" number=\" %1\" " ).arg (number + 1 );
2731
2741
trillXml += positioningAttributes (tr, false );
@@ -2798,7 +2808,7 @@ void ExportMusicXml::wavyLineStartStop(const ChordRest* const cr, Notations& not
2798
2808
static void tremoloSingleStartStop (Chord* chord, Notations& notations, Ornaments& ornaments, XmlWriter& xml)
2799
2809
{
2800
2810
Tremolo* tr = chord->tremolo ();
2801
- if (tr && ExportMusicXml::canWrite (tr) ) {
2811
+ if (tr) {
2802
2812
int count = 0 ;
2803
2813
TremoloType st = tr->tremoloType ();
2804
2814
QString type;
@@ -2843,7 +2853,7 @@ static void tremoloSingleStartStop(Chord* chord, Notations& notations, Ornaments
2843
2853
2844
2854
2845
2855
if (!type.isEmpty () && ((count > 0 && type != " unmeasured" ) || (count == 0 && type == " unmeasured" ))) {
2846
- notations.tag (xml);
2856
+ notations.tag (xml, tr );
2847
2857
ornaments.tag (xml);
2848
2858
QString tagName = " tremolo" ;
2849
2859
tagName += QString (" type=\" %1\" " ).arg (type);
@@ -2861,9 +2871,9 @@ static void tremoloSingleStartStop(Chord* chord, Notations& notations, Ornaments
2861
2871
static void fermatas (const QVector<Element*>& cra, XmlWriter& xml, Notations& notations)
2862
2872
{
2863
2873
for (const Element* e : cra) {
2864
- if (!e->isFermata () || ! ExportMusicXml::canWrite (e) )
2874
+ if (!e->isFermata ())
2865
2875
continue ;
2866
- notations.tag (xml);
2876
+ notations.tag (xml, e );
2867
2877
fermata (toFermata (e), xml);
2868
2878
}
2869
2879
}
@@ -3115,9 +3125,9 @@ static void writeChordLines(const Chord* const chord, XmlWriter& xml, Notations&
3115
3125
default :
3116
3126
qDebug (" unknown ChordLine subtype %d" , int (cl->chordLineType ()));
3117
3127
}
3118
- subtype += color2xml (cl);
3119
3128
if (!subtype.isEmpty ()) {
3120
- notations.tag (xml);
3129
+ subtype += color2xml (cl);
3130
+ notations.tag (xml, cl);
3121
3131
articulations.tag (xml);
3122
3132
xml.tagE (subtype);
3123
3133
}
@@ -3131,11 +3141,11 @@ static void writeChordLines(const Chord* const chord, XmlWriter& xml, Notations&
3131
3141
3132
3142
static void writeBreathMark (const Breath* const breath, XmlWriter& xml, Notations& notations, Articulations& articulations)
3133
3143
{
3134
- if (breath && ExportMusicXml::canWrite (breath) ) {
3144
+ if (breath) {
3135
3145
QString tagName;
3136
3146
QString type;
3137
3147
3138
- notations.tag (xml);
3148
+ notations.tag (xml, breath );
3139
3149
articulations.tag (xml);
3140
3150
if (breath->isCaesura ()) {
3141
3151
tagName = " caesura" ;
@@ -3214,9 +3224,6 @@ void ExportMusicXml::chordAttributes(Chord* chord, Notations& notations, Technic
3214
3224
// first the attributes whose elements are children of <articulations>
3215
3225
Articulations articulations;
3216
3226
for (const Articulation* a : na) {
3217
- if (!ExportMusicXml::canWrite (a))
3218
- continue ;
3219
-
3220
3227
SymId sid = a->symId ();
3221
3228
std::vector<QString> mxmlArtics = symIdToArtics (sid);
3222
3229
@@ -3237,7 +3244,7 @@ void ExportMusicXml::chordAttributes(Chord* chord, Notations& notations, Technic
3237
3244
mxmlArtic += color2xml (a);
3238
3245
mxmlArtic += positioningAttributes (a);
3239
3246
3240
- notations.tag (_xml);
3247
+ notations.tag (_xml, a );
3241
3248
articulations.tag (_xml);
3242
3249
_xml.tagE (mxmlArtic);
3243
3250
}
@@ -3251,8 +3258,6 @@ void ExportMusicXml::chordAttributes(Chord* chord, Notations& notations, Technic
3251
3258
// then the attributes whose elements are children of <ornaments>
3252
3259
Ornaments ornaments;
3253
3260
for (const Articulation* a : na) {
3254
- if (!ExportMusicXml::canWrite (a))
3255
- continue ;
3256
3261
if (!a->isOrnament ())
3257
3262
continue ;
3258
3263
@@ -3266,7 +3271,7 @@ void ExportMusicXml::chordAttributes(Chord* chord, Notations& notations, Technic
3266
3271
mxmlOrnam += QString (" placement=\" %1\" " ).arg (placement);
3267
3272
mxmlOrnam += color2xml (a);
3268
3273
3269
- notations.tag (_xml);
3274
+ notations.tag (_xml, a );
3270
3275
ornaments.tag (_xml);
3271
3276
_xml.tagE (mxmlOrnam);
3272
3277
// accidental-mark is missing
@@ -3279,9 +3284,6 @@ void ExportMusicXml::chordAttributes(Chord* chord, Notations& notations, Technic
3279
3284
3280
3285
// and finally the attributes whose elements are children of <technical>
3281
3286
for (const Articulation* a : na) {
3282
- if (!ExportMusicXml::canWrite (a))
3283
- continue ;
3284
-
3285
3287
SymId sid = a->symId ();
3286
3288
QString placement;
3287
3289
QString direction;
@@ -3303,7 +3305,7 @@ void ExportMusicXml::chordAttributes(Chord* chord, Notations& notations, Technic
3303
3305
3304
3306
QString mxmlTechn = symIdToTechn (sid);
3305
3307
if (!mxmlTechn.isEmpty ()) {
3306
- notations.tag (_xml);
3308
+ notations.tag (_xml, a );
3307
3309
technical.tag (_xml);
3308
3310
mxmlTechn += color2xml (a);
3309
3311
mxmlTechn += positioningAttributes (a);
@@ -3369,9 +3371,6 @@ void ExportMusicXml::chordAttributes(Chord* chord, Notations& notations, Technic
3369
3371
3370
3372
// check if all articulations were handled
3371
3373
for (const Articulation* a : na) {
3372
- if (!ExportMusicXml::canWrite (a))
3373
- continue ;
3374
-
3375
3374
SymId sid = a->symId ();
3376
3375
if (symIdToArtics (sid).empty ()
3377
3376
&& symIdToTechn (sid).isEmpty ()
@@ -3411,32 +3410,29 @@ static Arpeggio* findArpeggio(Note* note)
3411
3410
3412
3411
static void arpeggiate (Arpeggio* arp, bool front, bool back, XmlWriter& xml, Notations& notations)
3413
3412
{
3414
- if (!ExportMusicXml::canWrite (arp))
3415
- return ;
3416
-
3417
3413
QString tagName;
3418
3414
switch (arp->arpeggioType ()) {
3419
3415
case ArpeggioType::NORMAL:
3420
- notations.tag (xml);
3416
+ notations.tag (xml, arp );
3421
3417
tagName = " arpeggiate" ;
3422
3418
break ;
3423
3419
case ArpeggioType::UP: // fall through
3424
3420
case ArpeggioType::UP_STRAIGHT: // not supported by MusicXML, export as normal arpeggio
3425
- notations.tag (xml);
3421
+ notations.tag (xml, arp );
3426
3422
tagName = " arpeggiate direction=\" up\" " ;
3427
3423
break ;
3428
3424
case ArpeggioType::DOWN: // fall through
3429
3425
case ArpeggioType::DOWN_STRAIGHT: // not supported by MusicXML, export as normal arpeggio
3430
- notations.tag (xml);
3426
+ notations.tag (xml, arp );
3431
3427
tagName = " arpeggiate direction=\" down\" " ;
3432
3428
break ;
3433
3429
case ArpeggioType::BRACKET:
3434
3430
if (front) {
3435
- notations.tag (xml);
3431
+ notations.tag (xml, arp );
3436
3432
tagName = " non-arpeggiate type=\" bottom\" " ;
3437
3433
}
3438
3434
if (back) {
3439
- notations.tag (xml);
3435
+ notations.tag (xml, arp );
3440
3436
tagName = " non-arpeggiate type=\" top\" " ;
3441
3437
}
3442
3438
break ;
@@ -3666,12 +3662,9 @@ static void writeNotehead(XmlWriter& xml, const Note* const note)
3666
3662
static void writeFingering (XmlWriter& xml, Notations& notations, Technical& technical, const Note* const note)
3667
3663
{
3668
3664
for (const Element* e : note->el ()) {
3669
- if (!ExportMusicXml::canWrite (e))
3670
- continue ;
3671
-
3672
3665
if (e->type () == ElementType::FINGERING) {
3673
3666
const TextBase* f = toTextBase (e);
3674
- notations.tag (xml);
3667
+ notations.tag (xml, e );
3675
3668
technical.tag (xml);
3676
3669
QString t = MScoreTextToMXML::toPlainText (f->xmlText ());
3677
3670
QString attr;
@@ -4021,20 +4014,25 @@ void ExportMusicXml::chord(Chord* chord, int staff, const std::vector<Lyrics*>*
4021
4014
Technical technical;
4022
4015
4023
4016
const Tie* tieBack = note->tieBack ();
4024
- if (tieBack && ExportMusicXml::canWrite (tieBack) ) {
4025
- notations.tag (_xml);
4017
+ if (tieBack) {
4018
+ notations.tag (_xml, tieBack );
4026
4019
_xml.tagE (" tied type=\" stop\" " );
4027
4020
}
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
+ }
4028
4030
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 );
4031
4033
QString rest = slurTieLineStyle (tieFor);
4032
4034
_xml.tagE (QString (" tied type=\" start\" %1" ).arg (rest));
4033
4035
}
4034
- if (hasLaissezVibrer (chord)/* && ExportMusicXml::canWrite(laissezVibrer)*/ ) {
4035
- notations.tag (_xml);
4036
- _xml.tagE (" tied type=\" let-ring\" " );
4037
- }
4038
4036
4039
4037
if (note == nl.front ()) {
4040
4038
if (!grace)
@@ -4050,7 +4048,7 @@ void ExportMusicXml::chord(Chord* chord, int staff, const std::vector<Lyrics*>*
4050
4048
// write tablature string / fret
4051
4049
if (chord->staff () && chord->staff ()->isTabStaff (Fraction (0 ,1 )))
4052
4050
if (note->fret () >= 0 && note->string () >= 0 ) {
4053
- notations.tag (_xml);
4051
+ notations.tag (_xml, note );
4054
4052
technical.tag (_xml);
4055
4053
_xml.tag (" string" , note->string () + 1 );
4056
4054
_xml.tag (" fret" , note->fret ());
@@ -4061,11 +4059,11 @@ void ExportMusicXml::chord(Chord* chord, int staff, const std::vector<Lyrics*>*
4061
4059
arpeggiate (arp, note == nl.front (), note == nl.back (), _xml, notations);
4062
4060
}
4063
4061
for (Spanner* spanner : note->spannerFor ())
4064
- if (spanner->type () == ElementType::GLISSANDO && ExportMusicXml::canWrite (spanner) ) {
4062
+ if (spanner->type () == ElementType::GLISSANDO) {
4065
4063
gh.doGlissandoStart (static_cast <Glissando*>(spanner), notations, _xml);
4066
4064
}
4067
4065
for (Spanner* spanner : note->spannerBack ())
4068
- if (spanner->type () == ElementType::GLISSANDO && ExportMusicXml::canWrite (spanner) ) {
4066
+ if (spanner->type () == ElementType::GLISSANDO) {
4069
4067
gh.doGlissandoStop (static_cast <Glissando*>(spanner), notations, _xml);
4070
4068
}
4071
4069
// write glissando (only for last note)
@@ -5813,6 +5811,9 @@ static void measureStyle(XmlWriter& xml, Attributes& attr, const Measure* const
5813
5811
5814
5812
static bool commonAnnotations (ExportMusicXml* exp , const Element* e, int sstaff)
5815
5813
{
5814
+ if (!exp ->canWrite (e))
5815
+ return false ;
5816
+
5816
5817
bool instrChangeHandled = false ;
5817
5818
5818
5819
// note: the instrument change details are handled in ExportMusicXml::writeMeasureTracks,
@@ -7595,7 +7596,7 @@ void ExportMusicXml::writeMeasure(const Measure* const m,
7595
7596
writeInstrumentDetails (part->instrument (), _score->styleB (Sid::concertPitch));
7596
7597
}
7597
7598
else {
7598
- for (size_t staffIdx : _hiddenStaves) {
7599
+ for (int & staffIdx : _hiddenStaves) {
7599
7600
_attr.doAttr (_xml, true );
7600
7601
QString attributes;
7601
7602
if (staves > 1 )
0 commit comments