1 //=============================================================================
2 //  MuseScore
3 //  Music Composition & Notation
4 //
5 //  Copyright (C) 2002-2011 Werner Schweer
6 //
7 //  This program is free software; you can redistribute it and/or modify
8 //  it under the terms of the GNU General Public License version 2
9 //  as published by the Free Software Foundation and appearing in
10 //  the file LICENCE.GPL
11 //=============================================================================
12 
13 #include "mscore.h"
14 #include "segment.h"
15 #include "element.h"
16 #include "chord.h"
17 #include "note.h"
18 #include "score.h"
19 #include "beam.h"
20 #include "tuplet.h"
21 #include "text.h"
22 #include "measure.h"
23 #include "barline.h"
24 #include "part.h"
25 #include "repeat.h"
26 #include "staff.h"
27 #include "line.h"
28 #include "hairpin.h"
29 #include "ottava.h"
30 #include "sig.h"
31 #include "keysig.h"
32 #include "staffstate.h"
33 #include "instrchange.h"
34 #include "clef.h"
35 #include "timesig.h"
36 #include "system.h"
37 #include "xml.h"
38 #include "undo.h"
39 #include "harmony.h"
40 
41 namespace Ms {
42 
43 //---------------------------------------------------------
44 //   subTypeName
45 //---------------------------------------------------------
46 
subTypeName() const47 const char* Segment::subTypeName() const
48       {
49       return subTypeName(_segmentType);
50       }
51 
subTypeName(SegmentType t)52 const char* Segment::subTypeName(SegmentType t)
53       {
54       switch(t) {
55             case SegmentType::Invalid:              return "Invalid";
56             case SegmentType::BeginBarLine:         return "BeginBarLine";
57             case SegmentType::HeaderClef:           return "HeaderClef";
58             case SegmentType::Clef:                 return "Clef";
59             case SegmentType::KeySig:               return "Key Signature";
60             case SegmentType::Ambitus:              return "Ambitus";
61             case SegmentType::TimeSig:              return "Time Signature";
62             case SegmentType::StartRepeatBarLine:   return "Begin Repeat";
63             case SegmentType::BarLine:              return "BarLine";
64             case SegmentType::Breath:               return "Breath";
65             case SegmentType::ChordRest:            return "ChordRest";
66             case SegmentType::EndBarLine:           return "EndBarLine";
67             case SegmentType::KeySigAnnounce:       return "Key Sig Precaution";
68             case SegmentType::TimeSigAnnounce:      return "Time Sig Precaution";
69             default:
70                   return "??";
71             }
72       }
73 
74 //---------------------------------------------------------
75 //   setElement
76 //---------------------------------------------------------
77 
setElement(int track,Element * el)78 void Segment::setElement(int track, Element* el)
79       {
80       if (el) {
81             el->setParent(this);
82             _elist[track] = el;
83             setEmpty(false);
84             }
85       else {
86             _elist[track] = 0;
87             checkEmpty();
88             }
89       }
90 
91 //---------------------------------------------------------
92 //   remove
93 //---------------------------------------------------------
94 
removeElement(int track)95 void Segment::removeElement(int track)
96       {
97       Element* el = element(track);
98       if (el->isChordRest()) {
99             ChordRest* cr = (ChordRest*)el;
100             Beam* beam = cr->beam();
101             if (beam)
102                   beam->remove(cr);
103             Tuplet* tuplet = cr->tuplet();
104             if (tuplet)
105                   tuplet->remove(cr);
106             }
107       }
108 
109 //---------------------------------------------------------
110 //   Segment
111 //---------------------------------------------------------
112 
Segment(Measure * m)113 Segment::Segment(Measure* m)
114    : Element(m->score(), ElementFlag::EMPTY | ElementFlag::ENABLED | ElementFlag::NOT_SELECTABLE)
115       {
116       setParent(m);
117       init();
118       }
119 
Segment(Measure * m,SegmentType st,const Fraction & t)120 Segment::Segment(Measure* m, SegmentType st, const Fraction& t)
121    : Element(m->score(), ElementFlag::EMPTY | ElementFlag::ENABLED | ElementFlag::NOT_SELECTABLE)
122       {
123       setParent(m);
124 //      Q_ASSERT(t >= Fraction(0,1));
125 //      Q_ASSERT(t <= m->ticks());
126       _segmentType = st;
127       _tick = t;
128       init();
129       }
130 
131 //---------------------------------------------------------
132 //   Segment
133 //---------------------------------------------------------
134 
Segment(const Segment & s)135 Segment::Segment(const Segment& s)
136    : Element(s)
137       {
138       _segmentType        = s._segmentType;
139       _tick               = s._tick;
140       _extraLeadingSpace  = s._extraLeadingSpace;
141 
142       for (Element* e : s._annotations)
143             add(e->clone());
144 
145       _elist.reserve(s._elist.size());
146       for (Element* e : s._elist) {
147             Element* ne = 0;
148             if (e) {
149                   ne = e->clone();
150                   ne->setParent(this);
151                   }
152             _elist.push_back(ne);
153             }
154       _dotPosX = s._dotPosX;
155       _shapes  = s._shapes;
156       }
157 
158 //---------------------------------------------------------
159 //   setSegmentType
160 //---------------------------------------------------------
161 
setSegmentType(SegmentType t)162 void Segment::setSegmentType(SegmentType t)
163       {
164       Q_ASSERT(_segmentType != SegmentType::Clef || t != SegmentType::ChordRest);
165       _segmentType = t;
166       }
167 
168 //---------------------------------------------------------
169 //   setScore
170 //---------------------------------------------------------
171 
setScore(Score * score)172 void Segment::setScore(Score* score)
173       {
174       Element::setScore(score);
175       for (Element* e : _elist) {
176             if (e)
177                   e->setScore(score);
178             }
179       for (Element* e : _annotations)
180             e->setScore(score);
181       }
182 
~Segment()183 Segment::~Segment()
184       {
185       for (Element* e : _elist) {
186             if (!e)
187                   continue;
188             if (e->isTimeSig())
189                   e->staff()->removeTimeSig(toTimeSig(e));
190             delete e;
191             }
192       qDeleteAll(_annotations);
193       }
194 
195 //---------------------------------------------------------
196 //   init
197 //---------------------------------------------------------
198 
init()199 void Segment::init()
200       {
201       int staves = score()->nstaves();
202       int tracks = staves * VOICES;
203       _elist.assign(tracks, 0);
204       _dotPosX.assign(staves, 0.0);
205       _shapes.assign(staves, Shape());
206       }
207 
208 //---------------------------------------------------------
209 //   tick
210 //---------------------------------------------------------
211 
tick() const212 Fraction Segment::tick() const
213       {
214       return _tick + measure()->tick();
215       }
216 
217 //---------------------------------------------------------
218 //   next1
219 ///   return next \a Segment, don’t stop searching at end
220 ///   of \a Measure
221 //---------------------------------------------------------
222 
next1() const223 Segment* Segment::next1() const
224       {
225       if (next())
226             return next();
227       Measure* m = measure()->nextMeasure();
228       return m ? m->first() : 0;
229       }
230 
231 //---------------------------------------------------------
232 //   next1enabled
233 //---------------------------------------------------------
234 
next1enabled() const235 Segment* Segment::next1enabled() const
236       {
237       Segment* s = next1();
238       while (s && !s->enabled())
239             s = s->next1();
240       return s;
241       }
242 
243 //---------------------------------------------------------
244 //   next1MM
245 //---------------------------------------------------------
246 
next1MM() const247 Segment* Segment::next1MM() const
248       {
249       if (next())
250             return next();
251       Measure* m = measure()->nextMeasureMM();
252       return m ? m->first() : 0;
253       }
254 
next1(SegmentType types) const255 Segment* Segment::next1(SegmentType types) const
256       {
257       for (Segment* s = next1(); s; s = s->next1()) {
258             if (s->segmentType() & types)
259                   return s;
260             }
261       return 0;
262       }
263 
next1MM(SegmentType types) const264 Segment* Segment::next1MM(SegmentType types) const
265       {
266       for (Segment* s = next1MM(); s; s = s->next1MM()) {
267             if (s->segmentType() & types)
268                   return s;
269             }
270       return 0;
271       }
272 
next1MMenabled() const273 Segment* Segment::next1MMenabled() const
274       {
275       Segment* s = next1MM();
276       while (s && !s->enabled())
277             s = s->next1MM();
278       return s;
279       }
280 
281 //---------------------------------------------------------
282 //   next
283 //    got to next segment which has subtype in types
284 //---------------------------------------------------------
285 
next(SegmentType types) const286 Segment* Segment::next(SegmentType types) const
287       {
288       for (Segment* s = next(); s; s = s->next()) {
289             if (s->segmentType() & types)
290                   return s;
291             }
292       return 0;
293       }
294 
295 //---------------------------------------------------------
296 //   nextInStaff
297 ///   Returns next \c Segment in the staff with given index
298 //---------------------------------------------------------
299 
nextInStaff(int staffIdx,SegmentType type) const300 Segment* Segment::nextInStaff(int staffIdx, SegmentType type) const
301       {
302       Segment* s = next(type);
303       const int minTrack = staffIdx * VOICES;
304       const int maxTrack = (staffIdx + 1) * VOICES - 1;
305       while (s && !s->hasElements(minTrack, maxTrack))
306             s = s->next(type);
307       return s;
308       }
309 
310 //---------------------------------------------------------
311 //   prev
312 //    got to previous segment which has subtype in types
313 //---------------------------------------------------------
314 
prev(SegmentType types) const315 Segment* Segment::prev(SegmentType types) const
316       {
317       for (Segment* s = prev(); s; s = s->prev()) {
318             if (s->segmentType() & types)
319                   return s;
320             }
321       return 0;
322       }
323 
324 //---------------------------------------------------------
325 //   prev1
326 ///   return previous \a Segment, don’t stop searching at
327 ///   \a Measure begin
328 //---------------------------------------------------------
329 
prev1() const330 Segment* Segment::prev1() const
331       {
332       if (prev())
333             return prev();
334       Measure* m = measure()->prevMeasure();
335       return m ? m->last() : 0;
336       }
337 
prev1enabled() const338 Segment* Segment::prev1enabled() const
339       {
340       Segment* s = prev1();
341       while (s && !s->enabled())
342             s = s->prev1();
343       return s;
344       }
345 
prev1MM() const346 Segment* Segment::prev1MM() const
347       {
348       if (prev())
349             return prev();
350       Measure* m = measure()->prevMeasureMM();
351       return m ? m->last() : 0;
352       }
353 
prev1MMenabled() const354 Segment* Segment::prev1MMenabled() const
355       {
356       Segment* s = prev1MM();
357       while (s && !s->enabled())
358             s = s->prev1MM();
359       return s;
360       }
361 
prev1(SegmentType types) const362 Segment* Segment::prev1(SegmentType types) const
363       {
364       for (Segment* s = prev1(); s; s = s->prev1()) {
365             if (s->segmentType() & types)
366                   return s;
367             }
368       return 0;
369       }
370 
prev1MM(SegmentType types) const371 Segment* Segment::prev1MM(SegmentType types) const
372       {
373       for (Segment* s = prev1MM(); s; s = s->prev1MM()) {
374             if (s->segmentType() & types)
375                   return s;
376             }
377       return 0;
378       }
379 
380 //---------------------------------------------------------
381 //   nextCR
382 //    get next ChordRest Segment
383 //---------------------------------------------------------
384 
nextCR(int track,bool sameStaff) const385 Segment* Segment::nextCR(int track, bool sameStaff) const
386       {
387       int strack = track;
388       int etrack;
389       if (sameStaff) {
390             strack &= ~(VOICES-1);
391             etrack = strack + VOICES;
392             }
393       else {
394             etrack = strack + 1;
395             }
396       for (Segment* seg = next1(); seg; seg = seg->next1()) {
397             if (seg->isChordRestType()) {
398                   if (track == -1)
399                         return seg;
400                   for (int t = strack; t < etrack; ++t) {
401                         if (seg->element(t))
402                               return seg;
403                         }
404                   }
405             }
406       return 0;
407       }
408 
409 //---------------------------------------------------------
410 //   nextChordRest
411 //    get the next ChordRest, start at this segment
412 //---------------------------------------------------------
413 
nextChordRest(int track,bool backwards) const414 ChordRest* Segment::nextChordRest(int track, bool backwards) const
415       {
416       for (const Segment* seg = this; seg; seg = backwards ? seg->prev1() : seg->next1()) {
417             Element* el = seg->element(track);
418             if (el && el->isChordRest())
419                   return toChordRest(el);
420             }
421       return 0;
422       }
423 
element(int track) const424 Element* Segment::element(int track) const
425 {
426     int elementsCount = static_cast<int>(_elist.size());
427     if (track < 0 || track >= elementsCount) {
428         return nullptr;
429     }
430 
431     return _elist[track];
432 }
433 
434 //---------------------------------------------------------
435 //   insertStaff
436 //---------------------------------------------------------
437 
insertStaff(int staff)438 void Segment::insertStaff(int staff)
439       {
440       int track = staff * VOICES;
441       for (int voice = 0; voice < VOICES; ++voice)
442             _elist.insert(_elist.begin() + track, 0);
443       _dotPosX.insert(_dotPosX.begin()+staff, 0.0);
444       _shapes.insert(_shapes.begin()+staff, Shape());
445 
446       for (Element* e : _annotations) {
447             int staffIdx = e->staffIdx();
448             if (staffIdx >= staff && !e->systemFlag())
449                   e->setTrack(e->track() + VOICES);
450             }
451       fixStaffIdx();
452       }
453 
454 //---------------------------------------------------------
455 //   removeStaff
456 //---------------------------------------------------------
457 
removeStaff(int staff)458 void Segment::removeStaff(int staff)
459       {
460       int track = staff * VOICES;
461       _elist.erase(_elist.begin() + track, _elist.begin() + track + VOICES);
462       _dotPosX.erase(_dotPosX.begin() + staff);
463       _shapes.erase(_shapes.begin()+staff);
464 
465       for (Element* e : _annotations) {
466             int staffIdx = e->staffIdx();
467             if (staffIdx > staff && !e->systemFlag())
468                   e->setTrack(e->track() - VOICES);
469             }
470 
471       fixStaffIdx();
472       }
473 
474 //---------------------------------------------------------
475 //   checkElement
476 //---------------------------------------------------------
477 
checkElement(Element * el,int track)478 void Segment::checkElement(Element* el, int track)
479       {
480       // generated elements can be overwritten
481       if (_elist[track] && !_elist[track]->generated()) {
482             qDebug("add(%s): there is already a %s at track %d tick %d",
483                el->name(),
484                _elist[track]->name(),
485                track,
486                tick().ticks()
487                );
488 //            abort();
489             }
490       }
491 
492 //---------------------------------------------------------
493 //   add
494 //---------------------------------------------------------
495 
add(Element * el)496 void Segment::add(Element* el)
497       {
498 //      qDebug("%p segment %s add(%d, %d, %s)", this, subTypeName(), tick(), el->track(), el->name());
499 
500       el->setParent(this);
501 
502       int track = el->track();
503       Q_ASSERT(track != -1);
504       Q_ASSERT(el->score() == score());
505       Q_ASSERT(score()->nstaves() * VOICES == int(_elist.size()));
506       // make sure offset is correct for staff
507       if (el->isStyled(Pid::OFFSET))
508             el->setOffset(el->propertyDefault(Pid::OFFSET).toPointF());
509 
510       switch (el->type()) {
511             case ElementType::REPEAT_MEASURE:
512                   _elist[track] = el;
513                   setEmpty(false);
514                   break;
515 
516             case ElementType::TEMPO_TEXT:
517             case ElementType::DYNAMIC:
518             case ElementType::HARMONY:
519             case ElementType::SYMBOL:
520             case ElementType::FRET_DIAGRAM:
521             case ElementType::STAFF_TEXT:
522             case ElementType::SYSTEM_TEXT:
523             case ElementType::REHEARSAL_MARK:
524             case ElementType::MARKER:
525             case ElementType::IMAGE:
526             case ElementType::TEXT:
527             case ElementType::TREMOLOBAR:
528             case ElementType::TAB_DURATION_SYMBOL:
529             case ElementType::FIGURED_BASS:
530             case ElementType::FERMATA:
531             case ElementType::STICKING:
532                   _annotations.push_back(el);
533                   break;
534 
535             case ElementType::STAFF_STATE:
536                   if (toStaffState(el)->staffStateType() == StaffStateType::INSTRUMENT) {
537                         StaffState* ss = toStaffState(el);
538                         Part* part = el->part();
539                         part->setInstrument(ss->instrument(), tick());
540                         }
541                   _annotations.push_back(el);
542                   break;
543 
544             case ElementType::INSTRUMENT_CHANGE: {
545                   InstrumentChange* is = toInstrumentChange(el);
546                   Part* part = is->part();
547                   part->setInstrument(is->instrument(), tick());
548                   _annotations.push_back(el);
549                   break;
550                   }
551 
552             case ElementType::CLEF:
553                   Q_ASSERT(_segmentType == SegmentType::Clef || _segmentType == SegmentType::HeaderClef);
554                   checkElement(el, track);
555                   _elist[track] = el;
556                   if (!el->generated()) {
557                         el->staff()->setClef(toClef(el));
558 //                        updateNoteLines(this, el->track());   TODO::necessary?
559                         }
560                   setEmpty(false);
561                   break;
562 
563             case ElementType::TIMESIG:
564                   Q_ASSERT(segmentType() == SegmentType::TimeSig || segmentType() == SegmentType::TimeSigAnnounce);
565                   checkElement(el, track);
566                   _elist[track] = el;
567                   el->staff()->addTimeSig(toTimeSig(el));
568                   setEmpty(false);
569                   break;
570 
571             case ElementType::KEYSIG:
572                   Q_ASSERT(_segmentType == SegmentType::KeySig || _segmentType == SegmentType::KeySigAnnounce);
573                   checkElement(el, track);
574                   _elist[track] = el;
575                   if (!el->generated())
576                         el->staff()->setKey(tick(), toKeySig(el)->keySigEvent());
577                   setEmpty(false);
578                   break;
579 
580             case ElementType::CHORD:
581             case ElementType::REST:
582                   Q_ASSERT(_segmentType == SegmentType::ChordRest);
583                   {
584                   if (track % VOICES) {
585                         bool v;
586                         if (el->isChord()) {
587                               v = false;
588                               // consider chord visible if any note is visible
589                               Chord* c = toChord(el);
590                               for (Note* n : c->notes()) {
591                                     if (n->visible()) {
592                                           v = true;
593                                           break;
594                                           }
595                                     }
596                               }
597                         else
598                               v = el->visible();
599 
600                         if (v && measure()->score()->ntracks() > track)
601                               measure()->setHasVoices(track / VOICES, true);
602                         }
603                   // the tick position of a tuplet is the tick position of its
604                   // first element:
605 //                  ChordRest* cr = toChordRest(el);
606 //                  if (cr->tuplet() && !cr->tuplet()->elements().empty() && cr->tuplet()->elements().front() == cr && cr->tuplet()->tick() < 0)
607 //                        cr->tuplet()->setTick(cr->tick());
608                   score()->setPlaylistDirty();
609                   }
610                   // fall through
611 
612             case ElementType::BAR_LINE:
613             case ElementType::BREATH:
614                   if (track < score()->nstaves() * VOICES) {
615                         checkElement(el, track);
616                         _elist[track] = el;
617                         }
618                   setEmpty(false);
619                   break;
620 
621             case ElementType::AMBITUS:
622                   Q_ASSERT(_segmentType == SegmentType::Ambitus);
623                   checkElement(el, track);
624                   _elist[track] = el;
625                   setEmpty(false);
626                   break;
627 
628             default:
629                   qFatal("Segment::add() unknown %s", el->name());
630             }
631       }
632 
633 //---------------------------------------------------------
634 //   remove
635 //---------------------------------------------------------
636 
remove(Element * el)637 void Segment::remove(Element* el)
638       {
639 // qDebug("%p Segment::remove %s %p", this, el->name(), el);
640 
641       int track = el->track();
642 
643       switch(el->type()) {
644             case ElementType::CHORD:
645             case ElementType::REST:
646                   {
647                   _elist[track] = 0;
648                   int staffIdx = el->staffIdx();
649                   measure()->checkMultiVoices(staffIdx);
650                   // spanners with this cr as start or end element will need relayout
651                   SpannerMap& smap = score()->spannerMap();
652                   auto spanners = smap.findOverlapping(tick().ticks(), tick().ticks());
653                   for (auto interval : spanners) {
654                         Spanner* s = interval.value;
655                         Element* start = s->startElement();
656                         Element* end = s->endElement();
657                         if (s->startElement() == el)
658                               start = nullptr;
659                         if (s->endElement() == el)
660                               end = nullptr;
661                         if (start != s->startElement() || end != s->endElement())
662                               score()->undo(new ChangeStartEndSpanner(s, start, end));
663                         }
664                   score()->setPlaylistDirty();
665                   }
666                   break;
667 
668             case ElementType::REPEAT_MEASURE:
669                   _elist[track] = 0;
670                   break;
671 
672             case ElementType::DYNAMIC:
673             case ElementType::FIGURED_BASS:
674             case ElementType::FRET_DIAGRAM:
675             case ElementType::HARMONY:
676             case ElementType::IMAGE:
677             case ElementType::MARKER:
678             case ElementType::REHEARSAL_MARK:
679             case ElementType::STAFF_TEXT:
680             case ElementType::SYSTEM_TEXT:
681             case ElementType::SYMBOL:
682             case ElementType::TAB_DURATION_SYMBOL:
683             case ElementType::TEMPO_TEXT:
684             case ElementType::TEXT:
685             case ElementType::TREMOLOBAR:
686             case ElementType::FERMATA:
687             case ElementType::STICKING:
688                   removeAnnotation(el);
689                   break;
690 
691             case ElementType::STAFF_STATE:
692                   if (toStaffState(el)->staffStateType() == StaffStateType::INSTRUMENT) {
693                         Part* part = el->part();
694                         part->removeInstrument(tick());
695                         }
696                   removeAnnotation(el);
697                   break;
698 
699             case ElementType::INSTRUMENT_CHANGE:
700                   {
701                   InstrumentChange* is = toInstrumentChange(el);
702                   Part* part = is->part();
703                   part->removeInstrument(tick());
704                   }
705                   removeAnnotation(el);
706                   break;
707 
708             case ElementType::TIMESIG:
709                   _elist[track] = 0;
710                   el->staff()->removeTimeSig(toTimeSig(el));
711                   break;
712 
713             case ElementType::KEYSIG:
714                   Q_ASSERT(_elist[track] == el);
715 
716                   _elist[track] = 0;
717                   if (!el->generated())
718                         el->staff()->removeKey(tick());
719                   break;
720 
721             case ElementType::CLEF:
722                   el->staff()->removeClef(toClef(el));
723                   // updateNoteLines(this, el->track());
724                   // fall through
725 
726             case ElementType::BAR_LINE:
727             case ElementType::AMBITUS:
728                   _elist[track] = 0;
729                   break;
730 
731             case ElementType::BREATH:
732                   _elist[track] = 0;
733                   score()->setPause(tick(), 0);
734                   break;
735 
736             default:
737                   qFatal("Segment::remove() unknown %s", el->name());
738 
739             }
740       triggerLayout();
741       checkEmpty();
742       }
743 
744 //---------------------------------------------------------
745 //   segmentType
746 //    returns segment type suitable for storage of Element
747 //---------------------------------------------------------
748 
segmentType(ElementType type)749 SegmentType Segment::segmentType(ElementType type)
750       {
751       switch (type) {
752             case ElementType::CHORD:
753             case ElementType::REST:
754             case ElementType::REPEAT_MEASURE:
755             case ElementType::JUMP:
756             case ElementType::MARKER:
757                   return SegmentType::ChordRest;
758             case ElementType::CLEF:
759                   return SegmentType::Clef;
760             case ElementType::KEYSIG:
761                   return SegmentType::KeySig;
762             case ElementType::TIMESIG:
763                   return SegmentType::TimeSig;
764             case ElementType::BAR_LINE:
765                   return SegmentType::StartRepeatBarLine;
766             case ElementType::BREATH:
767                   return SegmentType::Breath;
768             default:
769                   qDebug("Segment:segmentType():  bad type: <%s>", Element::name(type));
770                   return SegmentType::Invalid;
771             }
772       }
773 
774 //---------------------------------------------------------
775 //   sortStaves
776 //---------------------------------------------------------
777 
sortStaves(QList<int> & dst)778 void Segment::sortStaves(QList<int>& dst)
779       {
780       std::vector<Element*> dl;
781       dl.reserve(dst.size());
782 
783       for (int i = 0; i < dst.size(); ++i) {
784             int startTrack = dst[i] * VOICES;
785             int endTrack   = startTrack + VOICES;
786             for (int k = startTrack; k < endTrack; ++k)
787                   dl.push_back(_elist[k]);
788             }
789       std::swap(_elist, dl);
790       QMap<int, int> map;
791       for (int k = 0; k < dst.size(); ++k) {
792             map.insert(dst[k], k);
793             }
794       for (Element* e : _annotations) {
795             if (!e->systemFlag())
796                   e->setTrack(map[e->staffIdx()] * VOICES + e->voice());
797             }
798       fixStaffIdx();
799       }
800 
801 //---------------------------------------------------------
802 //   fixStaffIdx
803 //---------------------------------------------------------
804 
fixStaffIdx()805 void Segment::fixStaffIdx()
806       {
807       int track = 0;
808       for (Element* e : _elist) {
809             if (e)
810                   e->setTrack(track);
811             ++track;
812             }
813       }
814 
815 //---------------------------------------------------------
816 //   checkEmpty
817 //---------------------------------------------------------
818 
checkEmpty() const819 void Segment::checkEmpty() const
820       {
821       if (!_annotations.empty()) {
822             setEmpty(false);
823             return;
824             }
825       setEmpty(true);
826       for (const Element* e : _elist) {
827             if (e) {
828                   setEmpty(false);
829                   break;
830                   }
831             }
832       }
833 
834 //---------------------------------------------------------
835 //   swapElements
836 //---------------------------------------------------------
837 
swapElements(int i1,int i2)838 void Segment::swapElements(int i1, int i2)
839       {
840       std::iter_swap(_elist.begin() + i1, _elist.begin() + i2);
841       if (_elist[i1])
842             _elist[i1]->setTrack(i1);
843       if (_elist[i2])
844             _elist[i2]->setTrack(i2);
845       triggerLayout();
846       }
847 
848 //---------------------------------------------------------
849 //   write
850 //---------------------------------------------------------
851 
write(XmlWriter & xml) const852 void Segment::write(XmlWriter& xml) const
853       {
854       if (written())
855             return;
856       setWritten(true);
857       if (_extraLeadingSpace.isZero())
858             return;
859       xml.stag(this);
860       xml.tag("leadingSpace", _extraLeadingSpace.val());
861       xml.etag();
862       }
863 
864 //---------------------------------------------------------
865 //   read
866 //---------------------------------------------------------
867 
read(XmlReader & e)868 void Segment::read(XmlReader& e)
869       {
870       while (e.readNextStartElement()) {
871             const QStringRef& tag(e.name());
872 
873             if (tag == "subtype")
874                   e.skipCurrentElement();
875             else if (tag == "leadingSpace")
876                   _extraLeadingSpace = Spatium(e.readDouble());
877             else if (tag == "trailingSpace")          // obsolete
878                   e.readDouble();
879             else
880                   e.unknown();
881             }
882       }
883 
884 //---------------------------------------------------------
885 //   getProperty
886 //---------------------------------------------------------
887 
getProperty(Pid propertyId) const888 QVariant Segment::getProperty(Pid propertyId) const
889       {
890       switch (propertyId) {
891             case Pid::TICK:
892                   return _tick;
893             case Pid::LEADING_SPACE:
894                   return extraLeadingSpace();
895             default:
896                   return Element::getProperty(propertyId);
897             }
898       }
899 
900 //---------------------------------------------------------
901 //   propertyDefault
902 //---------------------------------------------------------
903 
propertyDefault(Pid propertyId) const904 QVariant Segment::propertyDefault(Pid propertyId) const
905       {
906       switch (propertyId) {
907             case Pid::LEADING_SPACE:
908                   return Spatium(0.0);
909             default:
910                   return Element::getProperty(propertyId);
911             }
912       }
913 
914 //---------------------------------------------------------
915 //   setProperty
916 //---------------------------------------------------------
917 
setProperty(Pid propertyId,const QVariant & v)918 bool Segment::setProperty(Pid propertyId, const QVariant& v)
919       {
920       switch (propertyId) {
921             case Pid::TICK:
922                   setRtick(v.value<Fraction>());
923                   break;
924             case Pid::LEADING_SPACE:
925                   setExtraLeadingSpace(v.value<Spatium>());
926                   for (Element* e : _elist) {
927                         if(e)
928                               e->setGenerated(false);
929                         }
930                   break;
931             default:
932                   return Element::setProperty(propertyId, v);
933             }
934       triggerLayout();
935       return true;
936       }
937 
938 //---------------------------------------------------------
939 //   widthInStaff
940 //---------------------------------------------------------
941 
widthInStaff(int staffIdx,SegmentType t) const942 qreal Segment::widthInStaff(int staffIdx, SegmentType t) const
943       {
944       const qreal segX = x();
945       qreal nextSegX = segX;
946 
947       Segment* nextSeg = nextInStaff(staffIdx, t);
948       if (nextSeg)
949             nextSegX = nextSeg->x();
950       else {
951             Segment* lastSeg = measure()->lastEnabled();
952             if (lastSeg->segmentType() & t)
953                   nextSegX = lastSeg->x() + lastSeg->width();
954             else
955                   nextSegX = lastSeg->x();
956             }
957 
958       return nextSegX - segX;
959       }
960 
961 //---------------------------------------------------------
962 //   ticksInStaff
963 //---------------------------------------------------------
964 
ticksInStaff(int staffIdx) const965 Fraction Segment::ticksInStaff(int staffIdx) const
966       {
967       const Fraction segTick = tick();
968       Fraction nextSegTick = segTick;
969 
970       Segment* nextSeg = nextInStaff(staffIdx, durationSegmentsMask);
971       if (nextSeg)
972             nextSegTick = nextSeg->tick();
973       else {
974             Segment* lastSeg = measure()->last();
975             nextSegTick = lastSeg->tick() + lastSeg->ticks();
976             }
977 
978       return nextSegTick - segTick;
979       }
980 
981 //---------------------------------------------------------
982 //   splitsTuplet
983 //---------------------------------------------------------
984 
splitsTuplet() const985 bool Segment::splitsTuplet() const
986       {
987       for (Element* e : _elist) {
988             if (!(e && e->isChordRest()))
989                   continue;
990             ChordRest* cr = toChordRest(e);
991             Tuplet* t = cr->tuplet();
992             while (t) {
993                   if (cr != t->elements().front())
994                         return true;
995                   t = t->tuplet();
996                   }
997             }
998       return false;
999       }
1000 
1001 //---------------------------------------------------------
1002 //   operator<
1003 ///   return true if segment is before s in list
1004 //---------------------------------------------------------
1005 
operator <(const Segment & s) const1006 bool Segment::operator<(const Segment& s) const
1007       {
1008       if (tick() < s.tick())
1009             return true;
1010       if (tick() > s.tick())
1011             return false;
1012       for (Segment* ns = next1(); ns && (ns->tick() == s.tick()); ns = ns->next1()) {
1013             if (ns == &s)
1014                   return true;
1015             }
1016       return false;
1017       }
1018 
1019 //---------------------------------------------------------
1020 //   operator>
1021 ///   return true if segment is after s in list
1022 //---------------------------------------------------------
1023 
operator >(const Segment & s) const1024 bool Segment::operator>(const Segment& s) const
1025       {
1026       if (tick() > s.tick())
1027             return true;
1028       if (tick() < s.tick())
1029             return false;
1030       for (Segment* ns = prev1(); ns && (ns->tick() == s.tick()); ns = ns->prev1()) {
1031             if (ns == &s)
1032                   return true;
1033             }
1034       return false;
1035       }
1036 
1037 //---------------------------------------------------------
1038 //   hasElements
1039 ///  Returns true if the segment has at least one element.
1040 ///  Annotations are not considered.
1041 //---------------------------------------------------------
1042 
hasElements() const1043 bool Segment::hasElements() const
1044       {
1045       for (const Element* e : _elist) {
1046             if (e)
1047                   return true;
1048             }
1049       return false;
1050       }
1051 
1052 //---------------------------------------------------------
1053 //   hasElements
1054 ///  return true if an annotation of type type or and element is found in the track range
1055 //---------------------------------------------------------
1056 
hasElements(int minTrack,int maxTrack) const1057 bool Segment::hasElements(int minTrack, int maxTrack) const
1058       {
1059       for (int curTrack = minTrack; curTrack <= maxTrack; curTrack++)
1060             if (element(curTrack))
1061                   return true;
1062       return false;
1063       }
1064 
1065 //---------------------------------------------------------
1066 //   allElementsInvisible
1067 ///  return true if all elements in the segment are invisible
1068 //---------------------------------------------------------
1069 
allElementsInvisible() const1070 bool Segment::allElementsInvisible() const
1071       {
1072       if (isType(SegmentType::BarLineType | SegmentType::ChordRest | SegmentType::Breath))
1073             return false;
1074 
1075       for (Element* e : _elist) {
1076             if (e && e->visible() && !qFuzzyCompare(e->width(), 0.0))
1077                   return false;
1078             }
1079 
1080       return true;
1081       }
1082 
1083 //---------------------------------------------------------
1084 //   hasAnnotationOrElement
1085 ///  return true if an annotation of type type or and element is found in the track range
1086 //---------------------------------------------------------
1087 
hasAnnotationOrElement(ElementType type,int minTrack,int maxTrack) const1088 bool Segment::hasAnnotationOrElement(ElementType type, int minTrack, int maxTrack) const
1089       {
1090       for (const Element* e : _annotations)
1091             if (e->type() == type && e->track() >= minTrack && e->track() <= maxTrack)
1092                   return true;
1093       return hasElements(minTrack, maxTrack);
1094       }
1095 
1096 //---------------------------------------------------------
1097 //   findAnnotation
1098 ///  Returns the first found annotation of type type
1099 ///  or nullptr if nothing was found.
1100 //---------------------------------------------------------
1101 
findAnnotation(ElementType type,int minTrack,int maxTrack)1102 Element* Segment::findAnnotation(ElementType type, int minTrack, int maxTrack)
1103       {
1104       for (Element* e : _annotations)
1105             if (e->type() == type && e->track() >= minTrack && e->track() <= maxTrack)
1106                   return e;
1107       return nullptr;
1108       }
1109 
1110 //---------------------------------------------------------
1111 //   findAnnotations
1112 ///  Returns the list of found annotations
1113 ///  or nullptr if nothing was found.
1114 //---------------------------------------------------------
1115 
findAnnotations(ElementType type,int minTrack,int maxTrack)1116 std::vector<Element*> Segment::findAnnotations(ElementType type, int minTrack, int maxTrack)
1117       {
1118       std::vector<Element*> found;
1119       for (Element* e : _annotations)
1120             if (e->type() == type && e->track() >= minTrack && e->track() <= maxTrack)
1121                   found.push_back(e);
1122       return found;
1123       }
1124 
1125 //---------------------------------------------------------
1126 //   removeAnnotation
1127 //---------------------------------------------------------
1128 
removeAnnotation(Element * e)1129 void Segment::removeAnnotation(Element* e)
1130       {
1131       for (auto i = _annotations.begin(); i != _annotations.end(); ++i) {
1132             if (*i == e) {
1133                   _annotations.erase(i);
1134                   break;
1135                   }
1136             }
1137       }
1138 
1139 //---------------------------------------------------------
1140 //   clearAnnotations
1141 //---------------------------------------------------------
1142 
clearAnnotations()1143 void Segment::clearAnnotations()
1144       {
1145       _annotations.clear();
1146       }
1147 
1148 //---------------------------------------------------------
1149 //   elementAt
1150 //    A variant of the element(int) function,
1151 //    specifically intended to be called from QML plugins
1152 //---------------------------------------------------------
1153 
elementAt(int track) const1154 Ms::Element* Segment::elementAt(int track) const
1155       {
1156       Element* e = track < int(_elist.size()) ? _elist[track] : 0;
1157       return e;
1158       }
1159 
1160 //---------------------------------------------------------
1161 //   scanElements
1162 //---------------------------------------------------------
1163 
scanElements(void * data,void (* func)(void *,Element *),bool all)1164 void Segment::scanElements(void* data, void (*func)(void*, Element*), bool all)
1165       {
1166       for (int track = 0; track < score()->nstaves() * VOICES; ++track) {
1167             int staffIdx = track/VOICES;
1168             if (!all && !(score()->staff(staffIdx)->show() && system() && !system()->staves()->empty() && system()->staff(staffIdx)->show())) {
1169                   track += VOICES - 1;
1170                   continue;
1171                   }
1172             Element* e = element(track);
1173             if (e == 0)
1174                   continue;
1175             // if measure is not visible, handle visible End Bar Lines and Courtesy Clefs in certain conditions (for ossias and cutaway):
1176             if (!measure()->visible(staffIdx)) {
1177                   if (isEndBarLineType()) {
1178                         if (!measure()->nextMeasure())
1179                               continue;  // skip EndBarLines if next measure == NULL
1180                         else if (!measure()->isCutawayClef(staffIdx) &&
1181                                  !(measure()->nextMeasure()->visible(staffIdx) && measure()->nextMeasure()->system() == measure()->system()))
1182                               continue;  // skip if not on courtesy clef measures and if next measure in system is not visible
1183                         }
1184                   else if (isClefType()) {
1185                         if (!measure()->isCutawayClef(staffIdx))
1186                               continue;  // skip clefs except for courtesy clefs at the end of invisible measures
1187                         }
1188                   else
1189                         continue;
1190                   }
1191             e->scanElements(data, func, all);
1192             }
1193       for (Element* e : annotations()) {
1194             if (all || e->systemFlag() || measure()->visible(e->staffIdx()))
1195                   e->scanElements(data,  func, all);
1196             }
1197       }
1198 
1199 //---------------------------------------------------------
1200 //   firstElement
1201 //   This function returns the first main element from a
1202 //   segment, or a barline if it spanns in the staff
1203 //---------------------------------------------------------
1204 
firstElement(int staff)1205 Element* Segment::firstElement(int staff)
1206       {
1207       if (isChordRestType()) {
1208             int strack = staff * VOICES;
1209             int etrack = strack + VOICES;
1210             for (int v = strack; v < etrack; ++v) {
1211                   Element* el = element(v);
1212                   if (!el)
1213                         continue;
1214                   return el->isChord() ? toChord(el)->notes().back() : el;
1215                   }
1216             }
1217       else
1218             return getElement(staff);
1219       return 0;
1220       }
1221 
1222 //---------------------------------------------------------
1223 //   lastElement
1224 //   This function returns the last main element from a
1225 //   segment, or a barline if it spanns in the staff
1226 //---------------------------------------------------------
1227 
lastElement(int staff)1228 Element* Segment::lastElement(int staff)
1229       {
1230       if (segmentType() == SegmentType::ChordRest) {
1231             for (int voice = staff * VOICES + (VOICES - 1); voice/VOICES == staff; voice--) {
1232                   Element* el = element(voice);
1233                   if (!el) {      //there is no chord or rest on this voice
1234                         continue;
1235                         }
1236                   if (el->isChord()) {
1237                         return toChord(el)->notes().front();
1238                         }
1239                   else {
1240                         return el;
1241                         }
1242                  }
1243             }
1244       else {
1245             return getElement(staff);
1246             }
1247 
1248       return 0;
1249       }
1250 
1251 //---------------------------------------------------------
1252 //   getElement
1253 //   protected because it is used by the firstElement and
1254 //   lastElement functions when segment types that have
1255 //   just one element to avoid duplicated code
1256 //
1257 //   Use firstElement, or lastElement instead of this
1258 //---------------------------------------------------------
1259 
getElement(int staff)1260 Element* Segment::getElement(int staff)
1261       {
1262       segmentType();
1263       if (segmentType() == SegmentType::ChordRest) {
1264             return firstElement(staff);
1265       }
1266       else if (segmentType() & (SegmentType::EndBarLine | SegmentType::BarLine | SegmentType::StartRepeatBarLine)) {
1267             for (int i = staff; i >= 0; i--) {
1268                   if (!element(i * VOICES))
1269                         continue;
1270                   BarLine* b = toBarLine(element(i*VOICES));
1271                   if (i + b->spanStaff() >= staff)
1272                         return element(i*VOICES);
1273                   }
1274             }
1275       else
1276             return element(staff * VOICES);
1277       return 0;
1278       }
1279 
1280 //---------------------------------------------------------
1281 //   nextAnnotation
1282 //   return next element in _annotations
1283 //---------------------------------------------------------
1284 
nextAnnotation(Element * e)1285 Element* Segment::nextAnnotation(Element* e)
1286       {
1287       if (_annotations.empty() || e == _annotations.back())
1288             return nullptr;
1289       auto ei = std::find(_annotations.begin(), _annotations.end(), e);
1290       if (ei == _annotations.end())
1291             return nullptr;               // element not found
1292 
1293       // TODO: firstVisibleStaff() for system elements? see Spanner::nextSpanner()
1294       auto resIt = std::find_if(ei + 1, _annotations.end(), [e](Element* nextElem){
1295             return nextElem && nextElem->staffIdx() == e->staffIdx();
1296             });
1297 
1298       return _annotations.end() == resIt ? nullptr : *resIt;
1299       }
1300 
1301 //---------------------------------------------------------
1302 //   prevAnnotation
1303 //   return previous element in _annotations
1304 //---------------------------------------------------------
1305 
prevAnnotation(Element * e)1306 Element* Segment::prevAnnotation(Element* e)
1307       {
1308       if (e == _annotations.front())
1309           return nullptr;
1310       auto reverseIt = std::find(_annotations.rbegin(), _annotations.rend(), e);
1311       if (reverseIt == _annotations.rend())
1312             return nullptr;               // element not found
1313 
1314       // TODO: firstVisibleStaff() for system elements? see Spanner::nextSpanner()
1315       auto resIt = std::find_if(reverseIt + 1, _annotations.rend(), [e](Element* prevElem){
1316             return prevElem && prevElem->staffIdx() == e->staffIdx();
1317             });
1318 
1319       return _annotations.rend() == resIt ? nullptr : *resIt;
1320       }
1321 
1322 //---------------------------------------------------------
1323 //   firstAnnotation
1324 //---------------------------------------------------------
1325 
firstAnnotation(Segment * s,int activeStaff)1326 Element* Segment::firstAnnotation(Segment* s, int activeStaff)
1327       {
1328       for (auto i = s->annotations().begin(); i != s->annotations().end(); ++i) {
1329             // TODO: firstVisibleStaff() for system elements? see Spanner::nextSpanner()
1330             if ((*i)->staffIdx() == activeStaff)
1331                   return *i;
1332             }
1333       return nullptr;
1334       }
1335 
1336 //---------------------------------------------------------
1337 //   lastAnnotation
1338 //---------------------------------------------------------
1339 
lastAnnotation(Segment * s,int activeStaff)1340 Element* Segment::lastAnnotation(Segment* s, int activeStaff)
1341       {
1342       for (auto i = --s->annotations().end(); i != s->annotations().begin(); --i) {
1343             // TODO: firstVisibleStaff() for system elements? see Spanner::nextSpanner()
1344             if ((*i)->staffIdx() == activeStaff)
1345                   return *i;
1346             }
1347       auto i = s->annotations().begin();
1348       if ((*i)->staffIdx() == activeStaff)
1349             return *i;
1350       return nullptr;
1351       }
1352 
1353 //--------------------------------------------------------
1354 //   firstInNextSegments
1355 //   Searches for the next segment that has elements on the
1356 //   active staff and returns its first element
1357 //
1358 //   Uses firstElement so it also returns a barline if it
1359 //   spans into the active staff
1360 //--------------------------------------------------------
1361 
firstInNextSegments(int activeStaff)1362 Element* Segment::firstInNextSegments(int activeStaff)
1363       {
1364       Element* re = 0;
1365       Segment* seg = this;
1366       while (!re) {
1367             seg = seg->next1MMenabled();
1368             if (!seg) //end of staff, or score
1369                   break;
1370 
1371             re = seg->firstElement(activeStaff);
1372             }
1373 
1374       if (re)
1375             return re;
1376 
1377       if (!seg) { //end of staff
1378             if (activeStaff + 1 >= score()->nstaves()) //end of score
1379                   return 0;
1380             seg = score()->firstSegmentMM(SegmentType::All);
1381             return seg->element((activeStaff + 1) * VOICES);
1382             }
1383       return 0;
1384       }
1385 
1386 //---------------------------------------------------------
1387 //   firstElementOfSegment
1388 //   returns the first non null element in the given segment
1389 //---------------------------------------------------------
1390 
firstElementOfSegment(Segment * s,int activeStaff)1391 Element* Segment::firstElementOfSegment(Segment* s, int activeStaff)
1392       {
1393       for (auto i: s->elist()) {
1394             if (i && i->staffIdx() == activeStaff) {
1395                   if (i->type() == ElementType::CHORD)
1396                         return toChord(i)->notes().back();
1397                   else
1398                         return i;
1399                   }
1400             }
1401       return nullptr;
1402       }
1403 
1404 //---------------------------------------------------------
1405 //   nextElementOfSegment
1406 //   returns the next element in the given segment
1407 //---------------------------------------------------------
1408 
nextElementOfSegment(Segment * s,Element * e,int activeStaff)1409 Element* Segment::nextElementOfSegment(Segment* s, Element* e, int activeStaff)
1410       {
1411       for (int track = 0; track < score()->nstaves() * VOICES - 1; ++track) {
1412             if (s->element(track) == 0)
1413                   continue;
1414              Element* el = s->element(track);
1415              if (el == e) {
1416                  Element* next = s->element(track+1);
1417                  while (track < score()->nstaves() * VOICES - 1 &&
1418                         (!next || next->staffIdx() != activeStaff)) {
1419                        next = s->element(++track);
1420                        }
1421                  if (!next || next->staffIdx() != activeStaff)
1422                        return nullptr;
1423                  if (next->isChord())
1424                        return toChord(next)->notes().back();
1425                  else
1426                        return next;
1427              }
1428              if (el->type() == ElementType::CHORD) {
1429                    std::vector<Note*> notes = toChord(el)->notes();
1430                    auto i = std::find(notes.begin(), notes.end(), e);
1431                    if (i == notes.end())
1432                          continue;
1433                    if (i!= notes.begin()) {
1434                          return *(i-1);
1435                          }
1436                    else {
1437                          Element* nextEl = s->element(++track);
1438                          while (track < score()->nstaves() * VOICES - 1 &&
1439                                 (!nextEl || nextEl->staffIdx() != activeStaff)) {
1440                                nextEl = s->element(++track);
1441                                }
1442                          if (!nextEl || nextEl->staffIdx() != activeStaff)
1443                                return nullptr;
1444                          if (nextEl->isChord())
1445                                return toChord(nextEl)->notes().back();
1446                          return nextEl;
1447                          }
1448                    }
1449             }
1450       return nullptr;
1451       }
1452 
1453 //---------------------------------------------------------
1454 //   prevElementOfSegment
1455 //   returns the previous element in the given segment
1456 //---------------------------------------------------------
1457 
prevElementOfSegment(Segment * s,Element * e,int activeStaff)1458 Element* Segment::prevElementOfSegment(Segment* s, Element* e, int activeStaff)
1459       {
1460       for (int track = score()->nstaves() * VOICES - 1; track > 0; --track) {
1461             if (s->element(track) == 0)
1462                   continue;
1463              Element* el = s->element(track);
1464              if (el == e) {
1465                  Element* prev = s->element(track-1);
1466                  while (track > 0 &&
1467                         (!prev || prev->staffIdx() != activeStaff)) {
1468                        prev = s->element(--track);
1469                        }
1470                  if (!prev)
1471                        return nullptr;
1472                  if (prev->staffIdx() == e->staffIdx()) {
1473                  if (prev->isChord())
1474                        return toChord(prev)->notes().front();
1475                  else
1476                        return prev;
1477                        }
1478                  return nullptr;
1479              }
1480              if (el->isChord()) {
1481                    std::vector<Note*> notes = toChord(el)->notes();
1482                    auto i = std::find(notes.begin(), notes.end(), e);
1483                    if (i == notes.end())
1484                          continue;
1485                    if (i!= --notes.end()) {
1486                          return *(i+1);
1487                          }
1488                    else {
1489                          Element* prevEl = s->element(--track);
1490                          while (track > 0 &&
1491                                 (!prevEl || prevEl->staffIdx() != activeStaff)) {
1492                                prevEl = s->element(--track);
1493                                }
1494                          if (!prevEl)
1495                                return nullptr;
1496                          if (prevEl->staffIdx() == e->staffIdx()) {
1497                          if (prevEl->isChord())
1498                                return toChord(prevEl)->notes().front();
1499                          return prevEl;
1500                                }
1501                          return nullptr;
1502                          }
1503                    }
1504             }
1505       return nullptr;
1506       }
1507 
1508 //---------------------------------------------------------
1509 //   lastElementOfSegment
1510 //   returns the last element in the given segment
1511 //---------------------------------------------------------
1512 
lastElementOfSegment(Segment * s,int activeStaff)1513 Element* Segment::lastElementOfSegment(Segment* s, int activeStaff)
1514       {
1515       std::vector<Element*> elements = s->elist();
1516       for (auto i = --elements.end(); i != elements.begin(); --i) {
1517             if (*i && (*i)->staffIdx() == activeStaff) {
1518                   if ((*i)->isChord())
1519                       return toChord(*i)->notes().front();
1520                   else
1521                         return *i;
1522                   }
1523             }
1524       auto i = elements.begin();
1525       if (*i && (*i)->staffIdx() == activeStaff) {
1526             if ((*i)->type() == ElementType::CHORD)
1527                   return toChord(*i)->notes().front();
1528             else
1529                   return *i;
1530             }
1531       return nullptr;
1532       }
1533 
1534 //---------------------------------------------------------
1535 //   firstSpanner
1536 //---------------------------------------------------------
1537 
firstSpanner(int activeStaff)1538 Spanner* Segment::firstSpanner(int activeStaff)
1539       {
1540       std::multimap<int, Spanner*> mmap = score()->spanner();
1541       auto range = mmap.equal_range(tick().ticks());
1542       if (range.first != range.second){ // range not empty
1543             for (auto i = range.first; i != range.second; ++i) {
1544                   Spanner* s = i->second;
1545                   Element* e = s->startElement();
1546                   if (!e)
1547                         continue;
1548                   if (s->startSegment() == this) {
1549                         if (e->staffIdx() == activeStaff)
1550                               return s;
1551 #if 1
1552                         else if (e->isMeasure() && activeStaff == 0)
1553                               return s;
1554 #else
1555                         // TODO: see Spanner::nextSpanner()
1556                         else if (e->isMeasure()) {
1557                               SpannerSegment* ss = s->frontSegment();
1558                               int top = ss && ss->system() ? ss->system()->firstVisibleStaff() : 0;
1559                               if (activeStaff == top)
1560                                     return s;
1561                               }
1562 #endif
1563                         }
1564                   }
1565             }
1566       return nullptr;
1567       }
1568 
1569 //---------------------------------------------------------
1570 //   lastSpanner
1571 //---------------------------------------------------------
1572 
lastSpanner(int activeStaff)1573 Spanner* Segment::lastSpanner(int activeStaff)
1574       {
1575       std::multimap<int, Spanner*> mmap = score()->spanner();
1576       auto range = mmap.equal_range(tick().ticks());
1577       if (range.first != range.second){ // range not empty
1578             for (auto i = --range.second; ; --i) {
1579                   Spanner* s = i->second;
1580                   Element* e = s->startElement();
1581                   if (!e)
1582                         continue;
1583                   if (s->startSegment() == this) {
1584                         if (e->staffIdx() == activeStaff)
1585                               return s;
1586 #if 1
1587                         else if (e->isMeasure() && activeStaff == 0)
1588                               return s;
1589 #else
1590                         // TODO: see Spanner::nextSpanner()
1591                         else if (e->isMeasure()) {
1592                               SpannerSegment* ss = s->frontSegment();
1593                               int top = ss && ss->system() ? ss->system()->firstVisibleStaff() : 0;
1594                               if (activeStaff == top)
1595                                     return s;
1596                               }
1597 #endif
1598                         }
1599                   if (i == range.first)
1600                         break;
1601                   }
1602             }
1603       return nullptr;
1604       }
1605 
1606 
1607 
1608 //---------------------------------------------------------
1609 //   notChordRestType
1610 //---------------------------------------------------------
1611 
notChordRestType(Segment * s)1612 bool Segment::notChordRestType(Segment* s)
1613       {
1614       if (s->segmentType() == SegmentType::KeySig ||
1615           s->segmentType() == SegmentType::TimeSig ||
1616           s->segmentType() == SegmentType::Clef ||
1617           s->segmentType() == SegmentType::HeaderClef ||
1618           s->segmentType() == SegmentType::BeginBarLine ||
1619           s->segmentType() == SegmentType::EndBarLine ||
1620           s->segmentType() == SegmentType::BarLine ||
1621           s->segmentType() == SegmentType::KeySigAnnounce ||
1622           s->segmentType() == SegmentType::TimeSigAnnounce) {
1623             return true;
1624             }
1625       else {
1626             return false;
1627             }
1628       }
1629 
1630 //---------------------------------------------------------
1631 //   nextElement
1632 //---------------------------------------------------------
1633 
nextElement(int activeStaff)1634 Element* Segment::nextElement(int activeStaff)
1635       {
1636       Element* e = score()->selection().element();
1637       if (!e && !score()->selection().elements().isEmpty() )
1638             e = score()->selection().elements().first();
1639       if (!e)
1640             return nullptr;
1641       switch (e->type()) {
1642             case ElementType::DYNAMIC:
1643             case ElementType::HARMONY:
1644             case ElementType::SYMBOL:
1645             case ElementType::FERMATA:
1646             case ElementType::FRET_DIAGRAM:
1647             case ElementType::TEMPO_TEXT:
1648             case ElementType::STAFF_TEXT:
1649             case ElementType::SYSTEM_TEXT:
1650             case ElementType::REHEARSAL_MARK:
1651             case ElementType::MARKER:
1652             case ElementType::IMAGE:
1653             case ElementType::TEXT:
1654             case ElementType::TREMOLOBAR:
1655             case ElementType::TAB_DURATION_SYMBOL:
1656             case ElementType::FIGURED_BASS:
1657             case ElementType::STAFF_STATE:
1658             case ElementType::INSTRUMENT_CHANGE:
1659             case ElementType::STICKING: {
1660                   Element* next = nullptr;
1661                   if (e->parent() == this)
1662                         next = nextAnnotation(e);
1663                   if (next)
1664                         return next;
1665                   else {
1666                         Spanner* s = firstSpanner(activeStaff);
1667                         if (s)
1668                               return s->spannerSegments().front();
1669                         }
1670                   Segment* nextSegment = this->next1MMenabled();
1671                   while (nextSegment) {
1672                         Element* nextEl = nextSegment->firstElementOfSegment(nextSegment, activeStaff);
1673                         if (nextEl)
1674                               return nextEl;
1675                         nextSegment = nextSegment->next1MMenabled();
1676                         }
1677                   break;
1678                   }
1679             case ElementType::SEGMENT: {
1680                   if (!_annotations.empty()) {
1681                         Element* next = firstAnnotation(this, activeStaff);
1682                         if (next)
1683                               return next;
1684                         }
1685                   Spanner* sp = firstSpanner(activeStaff);
1686                   if (sp)
1687                         return sp->spannerSegments().front();
1688 
1689                   Segment* nextSegment = this->next1MMenabled();
1690                   while (nextSegment) {
1691                         Element* nextEl = nextSegment->firstElementOfSegment(nextSegment, activeStaff);
1692                         if (nextEl)
1693                               return nextEl;
1694                         nextSegment = nextSegment->next1MMenabled();
1695                         }
1696                   break;
1697                   }
1698             default: {
1699                   Element* p;
1700                   if (e->isTieSegment() || e->isGlissandoSegment()) {
1701                         SpannerSegment* s = toSpannerSegment(e);
1702                         Spanner* sp = s->spanner();
1703                         p = sp->startElement();
1704                         }
1705                   else {
1706                         p = e;
1707                         Element* pp = p->parent();
1708                         if (pp->isNote() || pp->isRest() || (pp->isChord() && !p->isNote()))
1709                               p = pp;
1710                         }
1711                   Element* el = p;
1712                   for (; p && p->type() != ElementType::SEGMENT; p = p->parent()) {
1713                         ;
1714                        }
1715                   Segment* seg = toSegment(p);
1716                   // next in _elist
1717                   Element* nextEl = nextElementOfSegment(seg, el, activeStaff);
1718                   if (nextEl)
1719                         return nextEl;
1720                   if (!_annotations.empty()) {
1721                         Element* next = firstAnnotation(seg, activeStaff);
1722                         if (next)
1723                               return next;
1724                         }
1725                   Spanner* s = firstSpanner(activeStaff);
1726                   if (s)
1727                         return s->spannerSegments().front();
1728                   Segment* nextSegment =  seg->next1MMenabled();
1729                   if (!nextSegment) {
1730                         MeasureBase* mb = measure()->next();
1731                         return mb && mb->isBox() ? mb : score()->lastElement();
1732                         }
1733 
1734                   Measure* nsm = nextSegment->measure();
1735                   if (nsm != measure()) {
1736                         // check for frame, measure elements
1737                         MeasureBase* nmb = measure()->nextMM();
1738                         Element* nme = nsm->el().empty() ? nullptr : nsm->el().front();
1739                         if (nsm != nmb)
1740                               return nmb;
1741                         else if (nme && nme->isTextBase() && nme->staffIdx() == e->staffIdx())
1742                               return nme;
1743                         else if (nme && nme->isLayoutBreak() && e->staffIdx() == 0)
1744                               return nme;
1745                         }
1746 
1747                   while (nextSegment) {
1748                         nextEl = nextSegment->firstElementOfSegment(nextSegment, activeStaff);
1749                         if (nextEl)
1750                               return nextEl;
1751                         nextSegment = nextSegment->next1MMenabled();
1752                         }
1753                   }
1754                   break;
1755             }
1756             return nullptr;
1757       }
1758 
1759 //---------------------------------------------------------
1760 //   prevElement
1761 //---------------------------------------------------------
1762 
prevElement(int activeStaff)1763 Element* Segment::prevElement(int activeStaff)
1764       {
1765       Element* e = score()->selection().element();
1766       if (!e && !score()->selection().elements().isEmpty() )
1767             e = score()->selection().elements().last();
1768       if (!e)
1769             return nullptr;
1770       switch (e->type()) {
1771             case ElementType::DYNAMIC:
1772             case ElementType::HARMONY:
1773             case ElementType::SYMBOL:
1774             case ElementType::FERMATA:
1775             case ElementType::FRET_DIAGRAM:
1776             case ElementType::TEMPO_TEXT:
1777             case ElementType::STAFF_TEXT:
1778             case ElementType::SYSTEM_TEXT:
1779             case ElementType::REHEARSAL_MARK:
1780             case ElementType::MARKER:
1781             case ElementType::IMAGE:
1782             case ElementType::TEXT:
1783             case ElementType::TREMOLOBAR:
1784             case ElementType::TAB_DURATION_SYMBOL:
1785             case ElementType::FIGURED_BASS:
1786             case ElementType::STAFF_STATE:
1787             case ElementType::INSTRUMENT_CHANGE:
1788             case ElementType::STICKING: {
1789                   Element* prev = nullptr;
1790                   if (e->parent() == this)
1791                         prev = prevAnnotation(e);
1792                   if (prev)
1793                         return prev;
1794                   if (notChordRestType(this)) {
1795                         Element* lastEl = lastElementOfSegment(this, activeStaff);
1796                         if (lastEl)
1797                               return lastEl;
1798                         }
1799                    int track = score()->nstaves() * VOICES - 1;
1800                    Segment* s = this;
1801                    Element* el = s->element(track);
1802                    while (track > 0 && (!el || el->staffIdx() != activeStaff)) {
1803                          el = s->element(--track);
1804                          if (track == 0) {
1805                                track = score()->nstaves() * VOICES - 1;
1806                                s = s->prev1MMenabled();
1807                                }
1808                          }
1809                    if (el->staffIdx() != activeStaff)
1810                          return nullptr;
1811                    if (el->type() == ElementType::CHORD || el->type() == ElementType::REST
1812                             || el->type() == ElementType::REPEAT_MEASURE) {
1813                          ChordRest* cr = this->cr(el->track());
1814                          if (cr) {
1815                                Element* elCr = cr->lastElementBeforeSegment();
1816                                if (elCr) {
1817                                      return elCr;
1818                                      }
1819                                }
1820                           }
1821                    if (el->type() == ElementType::CHORD) {
1822                          return toChord(el)->lastElementBeforeSegment();
1823                          }
1824                    else if (el->type() == ElementType::NOTE) {
1825                          Chord* c = toNote(el)->chord();
1826                          return c->lastElementBeforeSegment();
1827                          }
1828                    else {
1829                          return el;
1830                          }
1831                   }
1832             case ElementType::ARPEGGIO:
1833             case ElementType::TREMOLO: {
1834                   Element* el = this->element(e->track());
1835                   Q_ASSERT(el->type() == ElementType::CHORD);
1836                   return toChord(el)->prevElement();
1837                   }
1838             default: {
1839                   Element* el = e;
1840                   Segment* seg = this;
1841                   if (e->type() == ElementType::TIE_SEGMENT ||
1842                       e->type() == ElementType::GLISSANDO_SEGMENT) {
1843                         SpannerSegment* s = toSpannerSegment(e);
1844                         Spanner* sp = s->spanner();
1845                         el = sp->startElement();
1846                         seg = sp->startSegment();
1847                         }
1848                   else {
1849                         Element* ep = e->parent();
1850                         if (ep->isNote() || ep->isRest() || (ep->isChord() && !e->isNote()))
1851                               el = e->parent();
1852                         }
1853 
1854                  Element* prev = seg->prevElementOfSegment(seg, el, activeStaff);
1855                   if (prev) {
1856                         if (prev->type() == ElementType::CHORD || prev->type() == ElementType::REST
1857                                || prev->type() == ElementType::REPEAT_MEASURE) {
1858                               ChordRest* cr = seg->cr(prev->track());
1859                               if (cr) {
1860                                     Element* elCr = cr->lastElementBeforeSegment();
1861                                     if (elCr) {
1862                                           return elCr;
1863                                           }
1864                                     }
1865                               }
1866                         if (prev->type() == ElementType::CHORD) {
1867                               return toChord(prev)->lastElementBeforeSegment();
1868                               }
1869                         else if (prev->type() == ElementType::NOTE) {
1870                               Chord* c = toNote(prev)->chord();
1871                               return c->lastElementBeforeSegment();
1872                               }
1873                         else {
1874                               return prev;
1875                               }
1876                         }
1877                    Segment* prevSeg = seg->prev1MMenabled();
1878                    if (!prevSeg) {
1879                          MeasureBase* mb = measure()->prev();
1880                          return mb && mb->isBox() ? mb : score()->firstElement();
1881                          }
1882 
1883                    Measure* psm = prevSeg->measure();
1884                    if (psm != measure()) {
1885                          // check for frame, measure elements
1886                          MeasureBase* pmb = measure()->prevMM();
1887                          Element* me = measure()->el().empty() ? nullptr : measure()->el().back();
1888                          if (me && me->isTextBase() && me->staffIdx() == e->staffIdx())
1889                                return me;
1890                          else if (me && me->isLayoutBreak() && e->staffIdx() == 0)
1891                                return me;
1892                          else if (psm != pmb)
1893                               return pmb;
1894                          }
1895 
1896                    prev = lastElementOfSegment(prevSeg, activeStaff);
1897                    while (!prev && prevSeg) {
1898                          prevSeg = prevSeg->prev1MMenabled();
1899                          prev = lastElementOfSegment(prevSeg, activeStaff);
1900                          }
1901                    if (!prevSeg)
1902                          return score()->firstElement();
1903 
1904                    if (notChordRestType(prevSeg)) {
1905                          Element* lastEl = lastElementOfSegment(prevSeg, activeStaff);
1906                          if (lastEl)
1907                                return lastEl;
1908                          }
1909                    Spanner* s1 = prevSeg->lastSpanner(activeStaff);
1910                    if (s1) {
1911                          return s1->spannerSegments().front();
1912                          }
1913                    else if (!prevSeg->annotations().empty()) {
1914                          Element* next = lastAnnotation(prevSeg, activeStaff);
1915                          if (next)
1916                                return next;
1917                          }
1918                    if (prev->type() == ElementType::CHORD || prev->type() == ElementType::REST
1919                             || prev->type() == ElementType::REPEAT_MEASURE || prev->type() == ElementType::NOTE) {
1920                          ChordRest* cr = prevSeg->cr(prev->track());
1921                          if (cr) {
1922                                Element* elCr = cr->lastElementBeforeSegment();
1923                                if (elCr) {
1924                                      return elCr;
1925                                      }
1926                                }
1927                          }
1928                    if (prev->type() == ElementType::CHORD) {
1929                          return toChord(prev)->lastElementBeforeSegment();
1930                          }
1931                    else if (prev->type() == ElementType::NOTE) {
1932                          Chord* c = toNote(prev)->chord();
1933                          return c->lastElementBeforeSegment();
1934                          }
1935                    else {
1936                          return prev;
1937                          }
1938                   }
1939             }
1940       }
1941 
1942 //--------------------------------------------------------
1943 //   lastInPrevSegments
1944 //   Searches for the previous segment that has elements on
1945 //   the active staff and returns its last element
1946 //
1947 //   Uses lastElement so it also returns a barline if it
1948 //   spans into the active staff
1949 //--------------------------------------------------------
1950 
lastInPrevSegments(int activeStaff)1951 Element* Segment::lastInPrevSegments(int activeStaff)
1952       {
1953       Element* re = 0;
1954       Segment* seg = this;
1955 
1956       while (!re) {
1957             seg = seg->prev1MMenabled();
1958             if (!seg) //end of staff, or score
1959                   break;
1960 
1961             re = seg->lastElementOfSegment(seg, activeStaff);
1962             }
1963 
1964       if (re)
1965             return re;
1966 
1967       if (!seg) { //end of staff
1968             if (activeStaff - 1 < 0) //end of score
1969                   return 0;
1970 
1971             re = 0;
1972             seg = score()->lastSegmentMM();
1973             while (true) {
1974                   //if (seg->segmentType() == SegmentType::EndBarLine)
1975                   //      score()->inputState().setTrack((activeStaff - 1) * VOICES ); //correction
1976 
1977                   if ((re = seg->lastElement(activeStaff - 1)) != 0)
1978                         return re;
1979 
1980                   seg = seg->prev1MMenabled();
1981                   }
1982             }
1983 
1984       return 0;
1985       }
1986 
1987 //---------------------------------------------------------
1988 //   accessibleExtraInfo
1989 //---------------------------------------------------------
1990 
accessibleExtraInfo() const1991 QString Segment::accessibleExtraInfo() const
1992       {
1993       QString rez = "";
1994       if (!annotations().empty()) {
1995             QString temp = "";
1996             for (const Element* a : annotations()) {
1997                   if (!score()->selectionFilter().canSelect(a)) continue;
1998                   switch(a->type()) {
1999                         case ElementType::DYNAMIC:
2000                               //they are added in the chordrest, because they are for only one staff
2001                                break;
2002                         default:
2003                                temp = temp + " " + a->accessibleInfo();
2004                         }
2005                   }
2006             if(!temp.isEmpty())
2007                   rez = rez + QObject::tr("Annotations:") + temp;
2008             }
2009 
2010       QString startSpanners = "";
2011       QString endSpanners = "";
2012 
2013       auto spanners = score()->spannerMap().findOverlapping(tick().ticks(), tick().ticks());
2014       for (auto interval : spanners) {
2015             Spanner* s = interval.value;
2016             if (!score()->selectionFilter().canSelect(s)) continue;
2017             if (segmentType() == SegmentType::EndBarLine       ||
2018                segmentType() == SegmentType::BarLine           ||
2019                segmentType() == SegmentType::StartRepeatBarLine) {
2020                   if (s->isVolta())
2021                         continue;
2022                   }
2023             else {
2024                   if (s->isVolta() || s->isTie()) //ties are added in Note
2025                         continue;
2026                   }
2027 
2028             if (s->tick() == tick())
2029                   startSpanners += QObject::tr("Start of %1").arg(s->accessibleInfo());
2030 
2031             const Segment* seg = 0;
2032             switch (s->type()) {
2033                   case ElementType::VOLTA:
2034                   case ElementType::SLUR:
2035                         seg = this;
2036                         break;
2037                   default:
2038                         seg = next1MM(SegmentType::ChordRest);
2039                         break;
2040                   }
2041 
2042             if (seg && s->tick2() == seg->tick())
2043                   endSpanners += QObject::tr("End of %1").arg(s->accessibleInfo());
2044             }
2045       return rez + " " + startSpanners + " " + endSpanners;
2046       }
2047 
2048 //---------------------------------------------------------
2049 //   createShapes
2050 //---------------------------------------------------------
2051 
createShapes()2052 void Segment::createShapes()
2053       {
2054       setVisible(false);
2055       for (int staffIdx = 0; staffIdx < score()->nstaves(); ++staffIdx)
2056             createShape(staffIdx);
2057       }
2058 
2059 //---------------------------------------------------------
2060 //   createShape
2061 //---------------------------------------------------------
2062 
createShape(int staffIdx)2063 void Segment::createShape(int staffIdx)
2064       {
2065       Shape& s = _shapes[staffIdx];
2066       s.clear();
2067 
2068       if (segmentType() & (SegmentType::BarLine | SegmentType::EndBarLine | SegmentType::StartRepeatBarLine | SegmentType::BeginBarLine)) {
2069             setVisible(true);
2070             BarLine* bl = toBarLine(element(staffIdx * VOICES));
2071             if (bl) {
2072                   QRectF r = bl->layoutRect();
2073 #ifndef NDEBUG
2074                   s.add(r.translated(bl->pos()), bl->name());
2075 #else
2076                   s.add(r.translated(bl->pos()));
2077 #endif
2078                   }
2079             s.addHorizontalSpacing(Shape::SPACING_GENERAL, 0, 0);
2080             s.addHorizontalSpacing(Shape::SPACING_LYRICS, 0, 0);
2081             return;
2082             }
2083 #if 0
2084       for (int track = staffIdx * VOICES; track < (staffIdx + 1) * VOICES; ++track) {
2085             Element* e = _elist[track];
2086             if (e)
2087                   s.add(e->shape().translated(e->pos()));
2088             }
2089 #endif
2090 
2091       if (!score()->staff(staffIdx)->show())
2092             return;
2093 
2094       int strack = staffIdx * VOICES;
2095       int etrack = strack + VOICES;
2096       for (Element* e : _elist) {
2097             if (!e)
2098                   continue;
2099             int effectiveTrack = e->vStaffIdx() * VOICES + e->voice();
2100             if (effectiveTrack >= strack && effectiveTrack < etrack) {
2101                   setVisible(true);
2102                   if (e->addToSkyline())
2103                         s.add(e->shape().translated(e->pos()));
2104                   }
2105             }
2106 
2107       for (Element* e : _annotations) {
2108             if (!e || e->staffIdx() != staffIdx)
2109                   continue;
2110             setVisible(true);
2111             if (!e->addToSkyline())
2112                   continue;
2113 
2114             if (e->isHarmony()) {
2115                   // use same spacing calculation as for chordrest
2116                   toHarmony(e)->layout1();
2117                   const qreal margin = styleP(Sid::minHarmonyDistance) * 0.5;
2118                   qreal x1 = e->bbox().x() - margin + e->pos().x();
2119                   qreal x2 = e->bbox().x() + e->bbox().width() + margin + e->pos().x();
2120                   s.addHorizontalSpacing(Shape::SPACING_HARMONY, x1, x2);
2121                   }
2122             else if (!e->isRehearsalMark()
2123                && !e->isFretDiagram()
2124                && !e->isHarmony()
2125                && !e->isTempoText()
2126                && !e->isDynamic()
2127                && !e->isFiguredBass()
2128                && !e->isSymbol()
2129                && !e->isFSymbol()
2130                && !e->isSystemText()
2131                && !e->isInstrumentChange()
2132                && !e->isArticulation()
2133                && !e->isFermata()
2134                && !e->isStaffText()) {
2135                   // annotations added here are candidates for collision detection
2136                   // lyrics, ...
2137                   s.add(e->shape().translated(e->pos()));
2138                   }
2139             }
2140       }
2141 
2142 //---------------------------------------------------------
2143 //   minRight
2144 //    calculate minimum distance needed to the right
2145 //---------------------------------------------------------
2146 
minRight() const2147 qreal Segment::minRight() const
2148       {
2149       qreal distance = 0.0;
2150       for (const Shape& sh : shapes())
2151             distance = qMax(distance, sh.right());
2152       if (isClefType())
2153             distance += score()->styleP(Sid::clefBarlineDistance);
2154       return distance;
2155       }
2156 
2157 //---------------------------------------------------------
2158 //   minLeft
2159 //    Calculate minimum distance needed to the left shape
2160 //    sl. Sl is the same for all staves.
2161 //---------------------------------------------------------
2162 
minLeft(const Shape & sl) const2163 qreal Segment::minLeft(const Shape& sl) const
2164       {
2165       qreal distance = 0.0;
2166       for (const Shape& sh : shapes()) {
2167             qreal d = sl.minHorizontalDistance(sh);
2168             if (d > distance)
2169                   distance = d;
2170             }
2171       return distance;
2172       }
2173 
minLeft() const2174 qreal Segment::minLeft() const
2175       {
2176       qreal distance = 0.0;
2177       for (const Shape& sh : shapes()) {
2178             qreal l = sh.left();
2179             if (l > distance)
2180                   distance = l;
2181             }
2182       return distance;
2183       }
2184 
2185 //---------------------------------------------------------
2186 //   minHorizontalCollidingDistance
2187 //    calculate the minimum distance to ns avoiding collisions
2188 //---------------------------------------------------------
2189 
minHorizontalCollidingDistance(Segment * ns) const2190 qreal Segment::minHorizontalCollidingDistance(Segment* ns) const
2191       {
2192       qreal w = 0.0;
2193       for (unsigned staffIdx = 0; staffIdx < _shapes.size(); ++staffIdx) {
2194             qreal d = staffShape(staffIdx).minHorizontalDistance(ns->staffShape(staffIdx));
2195             w       = qMax(w, d);
2196             }
2197       return w;
2198       }
2199 
2200 //---------------------------------------------------------
2201 //   minHorizontalDistance
2202 //    calculate the minimum layout distance to Segment ns
2203 //---------------------------------------------------------
2204 
minHorizontalDistance(Segment * ns,bool systemHeaderGap) const2205 qreal Segment::minHorizontalDistance(Segment* ns, bool systemHeaderGap) const
2206       {
2207 
2208       qreal ww = -1000000.0;        // can remain negative
2209       for (unsigned staffIdx = 0; staffIdx < _shapes.size(); ++staffIdx) {
2210             qreal d = ns ? staffShape(staffIdx).minHorizontalDistance(ns->staffShape(staffIdx)) : 0.0;
2211             // first chordrest of a staff should clear the widest header for any staff
2212             // so make sure segment is as wide as it needs to be
2213             if (systemHeaderGap)
2214                   d = qMax(d, staffShape(staffIdx).right());
2215             ww      = qMax(ww, d);
2216             }
2217       qreal w = qMax(ww, 0.0);      // non-negative
2218 
2219       SegmentType st  = segmentType();
2220       SegmentType nst = ns ? ns->segmentType() : SegmentType::Invalid;
2221 
2222       if (isChordRestType()) {
2223             if (nst == SegmentType::EndBarLine) {
2224                   w = qMax(w, score()->noteHeadWidth());
2225                   w += score()->styleP(Sid::noteBarDistance);
2226                   }
2227             else if (nst == SegmentType::Clef) {
2228                   // clef likely does not exist on all staves
2229                   // and can cause very uneven spacing
2230                   // so use ww to avoid forcing margin except as necessary
2231                   w = ww + score()->styleP(Sid::clefLeftMargin);
2232                   }
2233             else {
2234                   bool isGap = false;
2235                   for (int i = 0; i < score()->nstaves() * VOICES; i++) {
2236                         Element* el = element(i);
2237                         if (!el)
2238                               continue;
2239                         if (el->isRest() && toRest(el)->isGap())
2240                               isGap = true;
2241                         else {
2242                               isGap = false;
2243                               break;
2244                               }
2245                         }
2246                   if (isGap)
2247                         return 0.0;
2248                   // minimum distance between notes is one note head width
2249                   w = qMax(w, score()->noteHeadWidth()) + score()->styleP(Sid::minNoteDistance);
2250                   }
2251             }
2252       else if (nst == SegmentType::ChordRest) {
2253             // <non ChordRest> - <ChordRest>
2254             if (systemHeaderGap) {
2255                   if (st == SegmentType::TimeSig)
2256                         w += score()->styleP(Sid::systemHeaderTimeSigDistance);
2257                   else
2258                         w += score()->styleP(Sid::systemHeaderDistance);
2259                   }
2260             else {
2261 //                  qreal d = score()->styleP(Sid::barNoteDistance);
2262 //                  qreal dd = minRight() + ns->minLeft() + spatium();
2263 //                  w = qMax(d, dd);
2264                   // not header
2265                   if (st == SegmentType::Clef)
2266                         w = ww + score()->styleP(Sid::midClefKeyRightMargin);
2267                   else if (st == SegmentType::KeySig)
2268                         w += score()->styleP(Sid::midClefKeyRightMargin);
2269                   else
2270                         w += score()->styleP(Sid::barNoteDistance);
2271 
2272                   if (st == SegmentType::StartRepeatBarLine) {
2273                         if (Element* barLine = element(0)) {
2274                               const qreal blWidth = barLine->width();
2275                               if (w < blWidth)
2276                                     w += blWidth;
2277                               }
2278                         }
2279                   }
2280             // d -= ns->minLeft() * .7;      // hack
2281             // d = qMax(d, ns->minLeft());
2282             // d = qMax(d, spatium());       // minimum distance is one spatium
2283             // w = qMax(w, minRight()) + d;
2284             }
2285       else if (systemHeaderGap) {
2286             // first segment after header is *not* a chordrest
2287             // could be a clef
2288             if (st == SegmentType::TimeSig)
2289                   w += score()->styleP(Sid::systemHeaderTimeSigDistance);
2290             else
2291                   w += score()->styleP(Sid::systemHeaderDistance);
2292             }
2293       else if (st & (SegmentType::Clef | SegmentType::HeaderClef)) {
2294             if (nst == SegmentType::KeySig || nst == SegmentType::KeySigAnnounce)
2295                   w += score()->styleP(Sid::clefKeyDistance);
2296             else if (nst == SegmentType::TimeSig || nst == SegmentType::TimeSigAnnounce)
2297                   w += score()->styleP(Sid::clefTimesigDistance);
2298             else if (nst & (SegmentType::EndBarLine | SegmentType::StartRepeatBarLine))
2299                   w += score()->styleP(Sid::clefBarlineDistance);
2300             else if (nst == SegmentType::Ambitus)
2301                   w += score()->styleP(Sid::ambitusMargin);
2302             }
2303       else if ((st & (SegmentType::KeySig | SegmentType::KeySigAnnounce))
2304          && (nst & (SegmentType::TimeSig | SegmentType::TimeSigAnnounce))) {
2305             w += score()->styleP(Sid::keyTimesigDistance);
2306             }
2307       else if (st == SegmentType::KeySig && nst == SegmentType::StartRepeatBarLine)
2308             w += score()->styleP(Sid::keyBarlineDistance);
2309       else if (st == SegmentType::StartRepeatBarLine)
2310             w += score()->styleP(Sid::noteBarDistance);
2311       else if (st == SegmentType::BeginBarLine && (nst & (SegmentType::HeaderClef | SegmentType::Clef)))
2312             w += score()->styleP(Sid::clefLeftMargin);
2313       else if (st == SegmentType::BeginBarLine && nst == SegmentType::KeySig)
2314             w += score()->styleP(Sid::keysigLeftMargin);
2315       else if (st == SegmentType::EndBarLine) {
2316             if (nst == SegmentType::KeySigAnnounce)
2317                   w += score()->styleP(Sid::keysigLeftMargin);
2318             else if (nst == SegmentType::TimeSigAnnounce)
2319                   w += score()->styleP(Sid::timesigLeftMargin);
2320             else if (nst == SegmentType::Clef)
2321                   w += score()->styleP(Sid::clefLeftMargin);
2322             }
2323       else if (st == SegmentType::TimeSig && nst == SegmentType::StartRepeatBarLine)
2324             w += score()->styleP(Sid::timesigBarlineDistance);
2325       else if (st == SegmentType::Breath)
2326             w += spatium() * 1.5;
2327       else if (st == SegmentType::Ambitus)
2328             w += score()->styleP(Sid::ambitusMargin);
2329 
2330       if (w < 0.0)
2331             w = 0.0;
2332       if (ns)
2333             w += ns->extraLeadingSpace().val() * spatium();
2334       return w;
2335       }
2336 
2337 }           // namespace Ms
2338