1 //=============================================================================
2 //  MuseScore
3 //  Music Composition & Notation
4 //
5 //  Copyright (C) 2002-2016 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 /**
14  \file
15  Implementation of most part of class Measure.
16 */
17 
18 #include "global/log.h"
19 
20 #include "measure.h"
21 #include "accidental.h"
22 #include "ambitus.h"
23 #include "articulation.h"
24 #include "barline.h"
25 #include "beam.h"
26 #include "box.h"
27 #include "bracket.h"
28 #include "breath.h"
29 #include "chord.h"
30 #include "clef.h"
31 #include "drumset.h"
32 #include "duration.h"
33 #include "dynamic.h"
34 #include "fermata.h"
35 #include "fret.h"
36 #include "glissando.h"
37 #include "hairpin.h"
38 #include "harmony.h"
39 #include "hook.h"
40 #include "icon.h"
41 #include "image.h"
42 #include "key.h"
43 #include "keysig.h"
44 #include "layoutbreak.h"
45 #include "layout.h"
46 #include "note.h"
47 #include "ottava.h"
48 #include "page.h"
49 #include "part.h"
50 #include "pedal.h"
51 #include "pitchspelling.h"
52 #include "repeat.h"
53 #include "rest.h"
54 #include "score.h"
55 #include "segment.h"
56 #include "select.h"
57 #include "sig.h"
58 #include "slur.h"
59 #include "spacer.h"
60 #include "staff.h"
61 #include "stafftext.h"
62 #include "stafftype.h"
63 #include "stringdata.h"
64 #include "style.h"
65 #include "sym.h"
66 #include "system.h"
67 #include "tempotext.h"
68 #include "measurenumber.h"
69 #include "mmrestrange.h"
70 #include "tie.h"
71 #include "tiemap.h"
72 #include "timesig.h"
73 #include "tremolo.h"
74 #include "trill.h"
75 #include "tuplet.h"
76 #include "tupletmap.h"
77 #include "undo.h"
78 #include "utils.h"
79 #include "volta.h"
80 #include "xml.h"
81 #include "systemdivider.h"
82 #include "stafftypechange.h"
83 #include "stafflines.h"
84 #include "bracketItem.h"
85 
86 namespace Ms {
87 
88 //---------------------------------------------------------
89 //   MStaff
90 ///   Per staff values of measure.
91 //---------------------------------------------------------
92 
93 class MStaff {
94       MeasureNumber* _noText { 0 };         ///< Measure number text object
95       MMRestRange* _mmRangeText { 0 };      ///< Multi measure rest range text object
96       StaffLines*  _lines    { 0 };
97       Spacer* _vspacerUp     { 0 };
98       Spacer* _vspacerDown   { 0 };
99       bool _hasVoices        { false };    ///< indicates that MStaff contains more than one voice,
100                                           ///< this changes some layout rules
101       bool _visible          { true  };
102       bool _stemless         { false };
103 #ifndef NDEBUG
104       bool _corrupted        { false };
105 #endif
106 
107    public:
MStaff()108       MStaff()  {}
109       ~MStaff();
110       MStaff(const MStaff&);
111 
112       void setScore(Score*);
113       void setTrack(int);
114 
noText() const115       MeasureNumber* noText() const   { return _noText;     }
setNoText(MeasureNumber * t)116       void setNoText(MeasureNumber* t) { _noText = t;        }
117 
mmRangeText() const118       MMRestRange *mmRangeText() const { return _mmRangeText; }
setMMRangeText(MMRestRange * r)119       void setMMRangeText(MMRestRange *r) { _mmRangeText = r; }
120 
lines() const121       StaffLines* lines() const      { return _lines; }
setLines(StaffLines * l)122       void setLines(StaffLines* l)   { _lines = l;    }
123 
vspacerUp() const124       Spacer* vspacerUp() const      { return _vspacerUp;   }
setVspacerUp(Spacer * s)125       void setVspacerUp(Spacer* s)   { _vspacerUp = s;      }
vspacerDown() const126       Spacer* vspacerDown() const    { return _vspacerDown; }
setVspacerDown(Spacer * s)127       void setVspacerDown(Spacer* s) { _vspacerDown = s;    }
128 
hasVoices() const129       bool hasVoices() const         { return _hasVoices;  }
setHasVoices(bool val)130       void setHasVoices(bool val)    { _hasVoices = val;   }
131 
visible() const132       bool visible() const           { return _visible;    }
setVisible(bool val)133       void setVisible(bool val)      { _visible = val;     }
134 
stemless() const135       bool stemless() const          { return _stemless; }
setStemless(bool val)136       void setStemless(bool val)     { _stemless = val;  }
137 
138 #ifndef NDEBUG
corrupted() const139       bool corrupted() const         { return _corrupted; }
setCorrupted(bool val)140       void setCorrupted(bool val)    { _corrupted = val; }
141 #endif
142       };
143 
~MStaff()144 MStaff::~MStaff()
145       {
146       delete _noText;
147       delete _mmRangeText;
148       delete _lines;
149       delete _vspacerUp;
150       delete _vspacerDown;
151       }
152 
MStaff(const MStaff & m)153 MStaff::MStaff(const MStaff& m)
154       {
155       _noText      = 0;
156       _mmRangeText = 0;
157       _lines       = new StaffLines(*m._lines);
158       _hasVoices   = m._hasVoices;
159       _vspacerUp   = 0;
160       _vspacerDown = 0;
161       _visible     = m._visible;
162       _stemless  = m._stemless;
163 #ifndef NDEBUG
164       _corrupted   = m._corrupted;
165 #endif
166       }
167 
168 //---------------------------------------------------------
169 //   MStaff::setScore
170 //---------------------------------------------------------
171 
setScore(Score * score)172 void MStaff::setScore(Score* score)
173       {
174       if (_lines)
175             _lines->setScore(score);
176       if (_vspacerUp)
177             _vspacerUp->setScore(score);
178       if (_vspacerDown)
179             _vspacerDown->setScore(score);
180       if (_noText)
181             _noText->setScore(score);
182       if (_mmRangeText)
183             _mmRangeText->setScore(score);
184       }
185 
186 //---------------------------------------------------------
187 //   setTrack
188 //---------------------------------------------------------
189 
setTrack(int track)190 void MStaff::setTrack(int track)
191       {
192       if (_lines)
193             _lines->setTrack(track);
194       if (_vspacerUp)
195             _vspacerUp->setTrack(track);
196       if (_vspacerDown)
197             _vspacerDown->setTrack(track);
198       if (_noText)
199             _noText->setTrack(track);
200       if(_mmRangeText)
201             _mmRangeText->setTrack(track);
202       }
203 
204 //---------------------------------------------------------
205 //   Measure
206 //---------------------------------------------------------
207 
Measure(Score * s)208 Measure::Measure(Score* s)
209    : MeasureBase(s), _timesig(4,4)
210       {
211       setTicks(Fraction(4,4));
212       _repeatCount           = 2;
213 
214       int n = score()->nstaves();
215       _mstaves.reserve(n);
216       for (int staffIdx = 0; staffIdx < n; ++staffIdx) {
217             MStaff* ms   = new MStaff;
218             Staff* staff = score()->staff(staffIdx);
219             ms->setLines(new StaffLines(score()));
220             ms->lines()->setTrack(staffIdx * VOICES);
221             ms->lines()->setParent(this);
222             ms->lines()->setVisible(!staff->invisible(tick()));
223             _mstaves.push_back(ms);
224             }
225       setIrregular(false);
226       _noMode                   = MeasureNumberMode::AUTO;
227       _userStretch              = 1.0;
228       _breakMultiMeasureRest    = false;
229       _mmRest                   = 0;
230       _mmRestCount              = 0;
231       setFlag(ElementFlag::MOVABLE, true);
232       }
233 
234 //---------------------------------------------------------
235 //   measure
236 //---------------------------------------------------------
237 
Measure(const Measure & m)238 Measure::Measure(const Measure& m)
239    : MeasureBase(m)
240       {
241       _segments     = m._segments.clone();
242       _timesig      = m._timesig;
243       _len          = m._len;
244       _repeatCount  = m._repeatCount;
245       _noMode       = m._noMode;
246       _userStretch  = m._userStretch;
247 
248       _mstaves.reserve(m._mstaves.size());
249       for (MStaff* ms : m._mstaves)
250             _mstaves.push_back(new MStaff(*ms));
251 
252       _breakMultiMeasureRest = m._breakMultiMeasureRest;
253       _mmRest                = m._mmRest;
254       _mmRestCount           = m._mmRestCount;
255       _playbackCount         = m._playbackCount;
256       }
257 
258 //---------------------------------------------------------
259 //   layoutStaffLines
260 //---------------------------------------------------------
261 
layoutStaffLines()262 void Measure::layoutStaffLines()
263       {
264       int staffIdx = 0;
265       for (MStaff* ms : _mstaves) {
266             if (isCutawayClef(staffIdx) && (score()->staff(staffIdx)->cutaway() || !visible(staffIdx)))
267                   // draw short staff lines for a courtesy clef on a hidden measure
268                   ms->lines()->layoutPartialWidth(width(), 4.0, true);
269             else
270                   // normal staff lines
271                   ms->lines()->layout();
272             staffIdx += 1;
273             }
274       }
275 
276 //---------------------------------------------------------
277 //   createStaves
278 //---------------------------------------------------------
279 
createStaves(int staffIdx)280 void Measure::createStaves(int staffIdx)
281       {
282       for (int n = int(_mstaves.size()); n <= staffIdx; ++n) {
283             Staff* staff = score()->staff(n);
284             MStaff* s    = new MStaff;
285             s->setLines(new StaffLines(score()));
286             s->lines()->setParent(this);
287             s->lines()->setTrack(n * VOICES);
288             s->lines()->setVisible(!staff->invisible(tick()));
289             _mstaves.push_back(s);
290             }
291       }
292 
293 //---------------------------------------------------------
294 //   setScore
295 //---------------------------------------------------------
296 
setScore(Score * score)297 void Measure::setScore(Score* score)
298       {
299       MeasureBase::setScore(score);
300       for (Segment* s = first(); s; s = s->next())
301             s->setScore(score);
302       }
303 
hasVoices(int staffIdx) const304 bool Measure::hasVoices(int staffIdx) const                     { return _mstaves[staffIdx]->hasVoices(); }
setHasVoices(int staffIdx,bool v)305 void Measure::setHasVoices(int staffIdx, bool v)                { return _mstaves[staffIdx]->setHasVoices(v); }
staffLines(int staffIdx)306 StaffLines* Measure::staffLines(int staffIdx)                   { return _mstaves[staffIdx]->lines(); }
vspacerDown(int staffIdx) const307 Spacer* Measure::vspacerDown(int staffIdx) const                { return _mstaves[staffIdx]->vspacerDown(); }
vspacerUp(int staffIdx) const308 Spacer* Measure::vspacerUp(int staffIdx) const                  { return _mstaves[staffIdx]->vspacerUp(); }
setStaffVisible(int staffIdx,bool visible)309 void Measure::setStaffVisible(int staffIdx, bool visible)       { _mstaves[staffIdx]->setVisible(visible); }
setStaffStemless(int staffIdx,bool stemless)310 void Measure::setStaffStemless(int staffIdx, bool stemless)     { _mstaves[staffIdx]->setStemless(stemless); }
311 
312 #ifndef NDEBUG
corrupted(int staffIdx) const313 bool Measure::corrupted(int staffIdx) const                     { return _mstaves[staffIdx]->corrupted(); }
setCorrupted(int staffIdx,bool val)314 void Measure::setCorrupted(int staffIdx, bool val)              { _mstaves[staffIdx]->setCorrupted(val); }
315 #endif
316 
setNoText(int staffIdx,MeasureNumber * t)317 void Measure::setNoText(int staffIdx, MeasureNumber* t)         { _mstaves[staffIdx]->setNoText(t); }
noText(int staffIdx) const318 MeasureNumber* Measure::noText(int staffIdx) const              { return _mstaves[staffIdx]->noText(); }
319 
setMMRangeText(int staffIdx,MMRestRange * t)320 void Measure::setMMRangeText(int staffIdx, MMRestRange* t)      { _mstaves[staffIdx]->setMMRangeText(t); }
mmRangeText(int staffIdx) const321 MMRestRange* Measure::mmRangeText(int staffIdx) const           { return _mstaves[staffIdx]->mmRangeText(); }
322 
323 //---------------------------------------------------------
324 //   Measure
325 //---------------------------------------------------------
326 
~Measure()327 Measure::~Measure()
328       {
329       for (Segment* s = first(); s;) {
330             Segment* ns = s->next();
331             delete s;
332             s = ns;
333             }
334       qDeleteAll(_mstaves);
335       }
336 
337 //---------------------------------------------------------
338 //   AcEl
339 //---------------------------------------------------------
340 
341 struct AcEl {
342       Note* note;
343       qreal x;
344       };
345 
346 //---------------------------------------------------------
347 //   findAccidental
348 ///   return current accidental value at note position
349 //---------------------------------------------------------
350 
findAccidental(Note * note) const351 AccidentalVal Measure::findAccidental(Note* note) const
352       {
353       Chord* chord = note->chord();
354       AccidentalState tversatz;  // state of already set accidentals for this measure
355       tversatz.init(chord->staff()->keySigEvent(tick()), chord->staff()->clef(tick()));
356 
357       for (Segment* segment = first(); segment; segment = segment->next()) {
358             int startTrack = chord->staffIdx() * VOICES;
359             if (segment->isKeySigType()) {
360                   KeySig* ks = toKeySig(segment->element(startTrack));
361                   if (!ks)
362                         continue;
363                   tversatz.init(chord->staff()->keySigEvent(segment->tick()), chord->staff()->clef(segment->tick()));
364                   }
365             else if (segment->segmentType() == SegmentType::ChordRest) {
366                   int endTrack   = startTrack + VOICES;
367                   for (int track = startTrack; track < endTrack; ++track) {
368                         Element* e = segment->element(track);
369                         if (!e || !e->isChord())
370                               continue;
371                         Chord* crd = toChord(e);
372                         for (Chord* chord1 : crd->graceNotes()) {
373                               for (Note* note1 : chord1->notes()) {
374                                     if (note1->tieBack() && note1->accidental() == 0)
375                                           continue;
376                                     //
377                                     // compute accidental
378                                     //
379                                     int tpc  = note1->tpc();
380                                     int line = absStep(tpc, note1->epitch());
381 
382                                     if (note == note1)
383                                           return tversatz.accidentalVal(line);
384                                     tversatz.setAccidentalVal(line, tpc2alter(tpc));
385                                     }
386                               }
387                         for (Note* note1 : crd->notes()) {
388                               if (note1->tieBack() && note1->accidental() == 0)
389                                     continue;
390                               //
391                               // compute accidental
392                               //
393                               int tpc  = note1->tpc();
394                               int line = absStep(tpc, note1->epitch());
395 
396                               if (note == note1)
397                                     return tversatz.accidentalVal(line);
398                               tversatz.setAccidentalVal(line, tpc2alter(tpc));
399                               }
400                         }
401                   }
402             }
403       qDebug("Measure::findAccidental: note not found");
404       return AccidentalVal::NATURAL;
405       }
406 
407 //---------------------------------------------------------
408 //   findAccidental
409 ///   Compute accidental state at segment/staffIdx for
410 ///   relative staff line.
411 //---------------------------------------------------------
412 
findAccidental(Segment * s,int staffIdx,int line,bool & error) const413 AccidentalVal Measure::findAccidental(Segment* s, int staffIdx, int line, bool &error) const
414       {
415       AccidentalState tversatz;  // state of already set accidentals for this measure
416       Staff* staff = score()->staff(staffIdx);
417       tversatz.init(staff->keySigEvent(tick()), staff->clef(tick()));
418 
419       SegmentType st = SegmentType::ChordRest;
420       int startTrack = staffIdx * VOICES;
421       int endTrack   = startTrack + VOICES;
422       for (Segment* segment = first(st); segment; segment = segment->next(st)) {
423             if (segment == s && staff->isPitchedStaff(tick())) {
424                   ClefType clef = staff->clef(s->tick());
425                   int l = relStep(line, clef);
426                   return tversatz.accidentalVal(l, error);
427                   }
428             for (int track = startTrack; track < endTrack; ++track) {
429                   Element* e = segment->element(track);
430                   if (!e || !e->isChord())
431                         continue;
432                   Chord* chord = toChord(e);
433                   for (Chord* chord1 : chord->graceNotes()) {
434                         for (Note* note : chord1->notes()) {
435                               if (note->tieBack() && note->accidental() == 0)
436                                     continue;
437                               int tpc  = note->tpc();
438                               int l    = absStep(tpc, note->epitch());
439                               tversatz.setAccidentalVal(l, tpc2alter(tpc));
440                               }
441                         }
442 
443                   for (Note* note : chord->notes()) {
444                         if (note->tieBack() && note->accidental() == 0)
445                               continue;
446                         int tpc    = note->tpc();
447                         int l      = absStep(tpc, note->epitch());
448                         tversatz.setAccidentalVal(l, tpc2alter(tpc));
449                         }
450                   }
451             }
452       qDebug("segment not found");
453       return AccidentalVal::NATURAL;
454       }
455 
456 //---------------------------------------------------------
457 //   tick2pos
458 ///    return x position for tick relative to System
459 //---------------------------------------------------------
460 
tick2pos(Fraction tck) const461 qreal Measure::tick2pos(Fraction tck) const
462       {
463       tck -= ticks();
464       if (isMMRest()) {
465             Segment* s = first(SegmentType::ChordRest);
466             qreal x1   = s->x();
467             qreal w    = width() - x1;
468             return x1 + (tck.ticks() * w) / (ticks().ticks() * mmRestCount());
469             }
470 
471       Segment* s;
472       qreal x1  = 0;
473       qreal x2  = 0;
474       Fraction tick1 = Fraction(0,1);
475       Fraction tick2 = Fraction(0,1);
476       for (s = first(SegmentType::ChordRest); s; s = s->next(SegmentType::ChordRest)) {
477             x2    = s->x();
478             tick2 = s->rtick();
479             if (tck == tick2)
480                   return x2 + pos().x();
481             if (tck <= tick2)
482                   break;
483             x1    = x2;
484             tick1 = tick2;
485             }
486       if (s == 0) {
487             x2    = width();
488             tick2 = ticks();
489             }
490       qreal dx = x2 - x1;
491       Fraction dt   = tick2 - tick1;
492       x1      += dt.isZero() ? 0.0 : (dx * (tck.ticks() - tick1.ticks()) / dt.ticks());
493       return x1 + pos().x();
494       }
495 
496 //---------------------------------------------------------
497 //   showsMeasureNumberInAutoMode
498 ///    Wheter the measure will show measure number(s) when MeasureNumberMode is set to AUTO
499 //---------------------------------------------------------
500 
showsMeasureNumberInAutoMode()501 bool Measure::showsMeasureNumberInAutoMode()
502       {
503       // Check wheter any measure number should be shown
504       if (!score()->styleB(Sid::showMeasureNumber))
505             return false;
506 
507       // Measure numbers should not be shown on irregular measures.
508       if (irregular())
509             return false;
510 
511       // Measure numbers should not show on first measure unless specified with Sid::showMeasureNumberOne
512       if (!no())
513             return score()->styleB(Sid::showMeasureNumberOne);
514 
515       if (score()->styleB(Sid::measureNumberSystem))
516             // Show either if
517             //   1) This is the first measure of the system OR
518             //   2) The previous measure in the system is the first, and is irregular.
519             return (isFirstInSystem()
520                     || (prevMeasure() && prevMeasure()->irregular() && prevMeasure()->isFirstInSystem()));
521       else {
522             // In the case of an interval, we should show the measure number either if:
523             //   1) We should show them every measure
524             int interval = score()->styleI(Sid::measureNumberInterval);
525             if (interval == 1)
526                   return true;
527 
528             //   2) (measureNumber + 1) % interval == 0 (or 1 if measure number one is numbered.)
529             // If measure number 1 is numbered, and the interval is let's say 5, then we should number #1, 6, 11, 16, etc.
530             // If measure number 1 is not numbered, with the same interval (5), then we should number #5, 10, 15, 20, etc.
531             return (((no() + 1) % score()->styleI(Sid::measureNumberInterval)) == (score()->styleB(Sid::showMeasureNumberOne) ? 1 : 0));
532             }
533       }
534 
535 //---------------------------------------------------------
536 //   showsMeasureNumber
537 ///     Wheter the Measure shows a MeasureNumber
538 //---------------------------------------------------------
539 
showsMeasureNumber()540 bool Measure::showsMeasureNumber()
541       {
542       if (_noMode == MeasureNumberMode::SHOW)
543             return true;
544       else if (_noMode == MeasureNumberMode::HIDE)
545             return false;
546       else {
547             return showsMeasureNumberInAutoMode();
548             }
549       }
550 
551 //---------------------------------------------------------
552 //   layoutMeasureNumber
553 ///    Layouts the Measure Numbers according to the Measure's MeasureNumberMode
554 //---------------------------------------------------------
555 
layoutMeasureNumber()556 void Measure::layoutMeasureNumber()
557       {
558       bool smn = showsMeasureNumber();
559 
560       QString s;
561       if (smn)
562             s = QString("%1").arg(no() + 1);
563 
564       unsigned nn = 1;
565       bool nas = score()->styleB(Sid::measureNumberAllStaves);
566 
567       if (!nas) {
568             //find first non invisible staff
569             for (unsigned staffIdx = 0; staffIdx < _mstaves.size(); ++staffIdx) {
570                   if (visible(staffIdx)) {
571                         nn = staffIdx;
572                         break;
573                         }
574                   }
575             }
576       for (unsigned staffIdx = 0; staffIdx < _mstaves.size(); ++staffIdx) {
577             MStaff* ms       = _mstaves[staffIdx];
578             MeasureNumber* t = ms->noText();
579             if (t)
580                   t->setTrack(staffIdx * VOICES);
581             if (smn && ((staffIdx == nn) || nas)) {
582                   if (t == 0) {
583                         t = new MeasureNumber(score());
584                         t->setTrack(staffIdx * VOICES);
585                         t->setGenerated(true);
586                         t->setParent(this);
587                         add(t);
588                         }
589                   t->setXmlText(s);
590                   t->layout();
591                   }
592             else {
593                   if (t) {
594                         if (t->generated())
595                               score()->removeElement(t);
596                         else
597                               score()->undo(new RemoveElement(t));
598                         }
599                   }
600             }
601       }
602 
layoutMMRestRange()603 void Measure::layoutMMRestRange()
604       {
605       if (!isMMRest() || !score()->styleB(Sid::mmRestShowMeasureNumberRange)) {
606             // Remove existing
607             for (unsigned staffIdx = 0; staffIdx < _mstaves.size(); ++staffIdx) {
608                   MStaff *ms = _mstaves[staffIdx];
609                   MMRestRange *rr = ms->mmRangeText();
610                   if (rr) {
611                         if (rr->generated())
612                               score()->removeElement(rr);
613                         else
614                               score()->undo(new RemoveElement(rr));
615                         }
616                   }
617 
618             return;
619             }
620 
621 
622       QString s;
623       if (mmRestCount() > 1) {
624             // middle char is an en dash (not em)
625             s = QString("%1–%2").arg(no() + 1).arg(no() + mmRestCount());
626             }
627       else {
628             // If the minimum range to create a mmrest is set to 1,
629             // then simply show the measure number as there is no range
630             s = QString("%1").arg(no() + 1);
631             }
632 
633       for (unsigned staffIdx = 0; staffIdx < _mstaves.size(); ++staffIdx) {
634             MStaff *ms = _mstaves[staffIdx];
635             MMRestRange *rr = ms->mmRangeText();
636             if (!rr) {
637                   rr = new MMRestRange(score());
638                   rr->setTrack(staffIdx * VOICES);
639                   rr->setGenerated(true);
640                   rr->setParent(this);
641                   add(rr);
642                   }
643             // setXmlText is reimplemented to take care of brackets
644             rr->setXmlText(s);
645             rr->layout();
646             }
647       }
648 
649 //---------------------------------------------------------
650 //   layout2
651 //    called after layout of page
652 //---------------------------------------------------------
653 
layout2()654 void Measure::layout2()
655       {
656       Q_ASSERT(parent());
657       Q_ASSERT(score()->nstaves() == int(_mstaves.size()));
658 
659       qreal _spatium = spatium();
660 
661       for (int staffIdx = 0; staffIdx < score()->nstaves(); ++staffIdx) {
662             MStaff* ms = _mstaves[staffIdx];
663             Spacer* sp = ms->vspacerDown();
664             if (sp) {
665                   sp->layout();
666                   Staff* staff = score()->staff(staffIdx);
667                   int n = staff->lines(tick()) - 1;
668                   qreal y = system()->staff(staffIdx)->y();
669                   sp->setPos(_spatium * .5, y + n * _spatium * staff->mag(tick()));
670                   }
671             sp = ms->vspacerUp();
672             if (sp) {
673                   sp->layout();
674                   qreal y = system()->staff(staffIdx)->y();
675                   sp->setPos(_spatium * .5, y - sp->gap());
676                   }
677             }
678 
679       MeasureBase::layout();  // layout LAYOUT_BREAK elements
680 
681       //---------------------------------------------------
682       //    layout ties
683       //---------------------------------------------------
684 
685       Fraction stick = system()->measures().front()->tick();
686       int tracks = score()->ntracks();
687       static const SegmentType st { SegmentType::ChordRest };
688       for (int track = 0; track < tracks; ++track) {
689             if (!score()->staff(track / VOICES)->show()) {
690                   track += VOICES-1;
691                   continue;
692                   }
693             for (Segment* seg = first(st); seg; seg = seg->next(st)) {
694                   ChordRest* cr = seg->cr(track);
695                   if (!cr)
696                         continue;
697 
698                   if (cr->isChord()) {
699                         Chord* c = toChord(cr);
700                         c->layoutSpanners(system(), stick);
701                         }
702                   }
703             }
704       }
705 
706 //---------------------------------------------------------
707 //   findChord
708 ///   Search for chord at position \a tick in \a track
709 //---------------------------------------------------------
710 
findChord(Fraction t,int track)711 Chord* Measure::findChord(Fraction t, int track)
712       {
713       t -= tick();
714       for (Segment* seg = last(); seg; seg = seg->prev()) {
715             if (seg->rtick() < t)
716                   return 0;
717             if (seg->rtick() == t) {
718                   Element* el = seg->element(track);
719                   if (el && el->isChord())
720                         return toChord(el);
721                   }
722             }
723       return 0;
724       }
725 
726 //---------------------------------------------------------
727 //   findChordRest
728 ///   Search for chord or rest at position \a tick at \a staff in \a voice.
729 //---------------------------------------------------------
730 
findChordRest(Fraction t,int track)731 ChordRest* Measure::findChordRest(Fraction t, int track)
732       {
733       t -= tick();
734       for (const Segment& seg : _segments) {
735             if (seg.rtick() > t)
736                   return 0;
737             if (seg.rtick() == t) {
738                   Element* el = seg.element(track);
739                   if (el && el->isChordRest())
740                         return toChordRest(el);
741                   }
742             }
743       return 0;
744       }
745 
746 //---------------------------------------------------------
747 //   tick2segment
748 //---------------------------------------------------------
749 
tick2segment(const Fraction & _t,SegmentType st)750 Segment* Measure::tick2segment(const Fraction& _t, SegmentType st)
751       {
752       Fraction t = _t - tick();
753       for (Segment& s : _segments) {
754             if (s.rtick() == t) {
755                   if (s.segmentType() & st)
756                         return &s;
757                   }
758             if (s.rtick() > t)
759                   break;
760             }
761       return 0;
762       }
763 
764 //---------------------------------------------------------
765 //   findSegmentR
766 //    Search for a segment of type st at measure relative
767 //    position t.
768 //---------------------------------------------------------
769 
findSegmentR(SegmentType st,const Fraction & t) const770 Segment* Measure::findSegmentR(SegmentType st, const Fraction& t) const
771       {
772       Segment* s;
773       if (t > (ticks() * Fraction(1,2))) {
774             // search backwards
775             for (s = last(); s && s->rtick() > t; s = s->prev())
776                   ;
777             while (s && s->prev() && s->prev()->rtick() == t)
778                   s = s->prev();
779             }
780       else {
781             // search forwards
782             for (s = first(); s && s->rtick() < t; s = s->next())
783                   ;
784             }
785       for (; s && s->rtick() == t; s = s->next()) {
786             if (s->segmentType() & st)
787                   return s;
788             }
789       return 0;
790       }
791 
792 //---------------------------------------------------------
793 //   undoGetSegmentR
794 //---------------------------------------------------------
795 
undoGetSegmentR(SegmentType type,const Fraction & t)796 Segment* Measure::undoGetSegmentR(SegmentType type, const Fraction& t)
797       {
798       Segment* s = findSegmentR(type, t);
799       if (s == 0) {
800             s = new Segment(this, type, t);
801             score()->undoAddElement(s);
802             }
803       return s;
804       }
805 
806 //---------------------------------------------------------
807 //   findFirstR
808 //    return first segment of type st at relative
809 //    position t.
810 //---------------------------------------------------------
811 
findFirstR(SegmentType st,const Fraction & t) const812 Segment* Measure::findFirstR(SegmentType st, const Fraction& t) const
813       {
814       Segment* s;
815       // search forwards
816       for (s = first(); s && s->rtick() <= t; s = s->next()) {
817             if (s->segmentType() == st)
818                   return s;
819             }
820       return 0;
821       }
822 
823 //---------------------------------------------------------
824 //   getSegmentR
825 ///   Get a segment of type st at relative tick position t.
826 ///   If the segment does not exist, it is created.
827 //---------------------------------------------------------
828 
getSegmentR(SegmentType st,const Fraction & t)829 Segment* Measure::getSegmentR(SegmentType st, const Fraction& t)
830       {
831       Segment* s = findSegmentR(st, t);
832       if (!s) {
833             s = new Segment(this, st, t);
834             add(s);
835             }
836       return s;
837       }
838 
839 //---------------------------------------------------------
840 //   add
841 ///   Add new Element \a el to Measure.
842 //---------------------------------------------------------
843 
add(Element * e)844 void Measure::add(Element* e)
845       {
846       e->setParent(this);
847       ElementType type = e->type();
848 
849       switch (type) {
850             case ElementType::SEGMENT:
851                   {
852                   Segment* seg   = toSegment(e);
853                   Fraction t     = seg->rtick();
854                   SegmentType st = seg->segmentType();
855                   Segment* s;
856 
857                   for (s = first(); s && s->rtick() < t; s = s->next())
858                         ;
859                   while (s && s->rtick() == t) {
860                         if (!seg->isChordRestType() && (seg->segmentType() == s->segmentType())) {
861                               qDebug("there is already a <%s> segment", seg->subTypeName());
862                               return;
863                               }
864                         if (s->segmentType() > st)
865                               break;
866                         s = s->next();
867                         }
868                   seg->setParent(this);
869                   _segments.insert(seg, s);
870                   //
871                   // update measure flags
872                   //
873                   if (seg->header())
874                         seg->measure()->setHeader(true);
875                   if (seg->trailer())
876                         seg->measure()->setTrailer(true);
877                   }
878                   break;
879 
880             case ElementType::MEASURE_NUMBER:
881                   if (e->staffIdx() < int(_mstaves.size())) {
882                         if (e->isStyled(Pid::OFFSET))
883                               e->setOffset(e->propertyDefault(Pid::OFFSET).toPointF());
884                         _mstaves[e->staffIdx()]->setNoText(toMeasureNumber(e));
885                         }
886                   break;
887 
888             case ElementType::MMREST_RANGE:
889                   if (e->staffIdx() < int(_mstaves.size())) {
890                         if (e->isStyled(Pid::OFFSET))
891                               e->setOffset(e->propertyDefault(Pid::OFFSET).toPointF());
892                         _mstaves[e->staffIdx()]->setMMRangeText(toMMRestRange(e));
893                         }
894                   break;
895 
896             case ElementType::SPACER:
897                   {
898                   Spacer* sp = toSpacer(e);
899                   switch (sp->spacerType()) {
900                         case SpacerType::UP:
901                               _mstaves[e->staffIdx()]->setVspacerUp(sp);
902                               break;
903                         case SpacerType::DOWN:
904                         case SpacerType::FIXED:
905                               _mstaves[e->staffIdx()]->setVspacerDown(sp);
906                               break;
907                         }
908                   sp->setGap(sp->gap());  // trigger relayout
909                   }
910                   break;
911             case ElementType::JUMP:
912                   setRepeatJump(true);
913                   // fall through
914 
915             case ElementType::MARKER:
916                   el().push_back(e);
917                   break;
918 
919             case ElementType::HBOX:
920                   if (e->staff())
921                         e->setMag(e->staff()->mag(tick()));     // ?!
922                   el().push_back(e);
923                   break;
924 
925             case ElementType::MEASURE:
926                   _mmRest = toMeasure(e);
927                   break;
928 
929             case ElementType::STAFFTYPE_CHANGE:
930                   {
931                   StaffTypeChange* stc = toStaffTypeChange(e);
932                   Staff* staff = stc->staff();
933                   const StaffType* st = stc->staffType();
934                   StaffType* nst;
935                   // st needs to point to the stafftype element within the stafftypelist for the staff
936                   if (st) {
937                         // executed on read, undo/redo, clone
938                         // setStaffType adds a copy to list and returns a pointer to that element within list
939                         // we won't need the original after that
940                         // this requires that st was allocated via new to begin with!
941                         nst = staff->setStaffType(tick(), *st);
942                         delete st;
943                         }
944                   else {
945                         // executed on add from palette
946                         // staffType returns a pointer to the current stafftype element in the list
947                         // setStaffType will make a copy and return a pointer to that element within list
948                         st  = staff->staffType(tick());
949                         nst = staff->setStaffType(tick(), *st);
950                         }
951                   staff->staffTypeListChanged(tick());
952                   stc->setStaffType(nst);
953                   MeasureBase::add(e);
954                   }
955                   break;
956 
957             default:
958                   MeasureBase::add(e);
959                   break;
960             }
961       }
962 
963 //---------------------------------------------------------
964 //   remove
965 ///   Remove Element \a el from Measure.
966 //---------------------------------------------------------
967 
remove(Element * e)968 void Measure::remove(Element* e)
969       {
970       Q_ASSERT(e->parent() == this);
971       Q_ASSERT(e->score() == score());
972 
973       switch (e->type()) {
974             case ElementType::SEGMENT:
975                   {
976                   Segment* s = toSegment(e);
977                   _segments.remove(s);
978                   //
979                   // update measure flags
980                   //
981                   if (s->header())
982                         s->measure()->checkHeader();
983                   if (s->trailer())
984                         s->measure()->checkTrailer();
985                   }
986                   break;
987 
988             case ElementType::MEASURE_NUMBER:
989                   _mstaves[e->staffIdx()]->setNoText(nullptr);
990                   break;
991 
992             case ElementType::MMREST_RANGE:
993                   _mstaves[e->staffIdx()]->setMMRangeText(nullptr);
994                   break;
995 
996             case ElementType::SPACER:
997                   switch (toSpacer(e)->spacerType()) {
998                         case SpacerType::DOWN:
999                         case SpacerType::FIXED:
1000                               _mstaves[e->staffIdx()]->setVspacerDown(0);
1001                               break;
1002                         case SpacerType::UP:
1003                               _mstaves[e->staffIdx()]->setVspacerUp(0);
1004                               break;
1005                         }
1006                   break;
1007 
1008             case ElementType::JUMP:
1009                   setRepeatJump(false);
1010                   // fall through
1011 
1012             case ElementType::MARKER:
1013             case ElementType::HBOX:
1014                   if (!el().remove(e)) {
1015                         qDebug("Measure(%p)::remove(%s,%p) not found", this, e->name(), e);
1016                         }
1017                   break;
1018 
1019             case ElementType::CLEF:
1020             case ElementType::CHORD:
1021             case ElementType::REST:
1022             case ElementType::TIMESIG:
1023                   for (Segment* segment = first(); segment; segment = segment->next()) {
1024                         int staves = score()->nstaves();
1025                         int tracks = staves * VOICES;
1026                         for (int track = 0; track < tracks; ++track) {
1027                               Element* ee = segment->element(track);
1028                               if (ee == e) {
1029                                     segment->setElement(track, 0);
1030                                     return;
1031                                     }
1032                               }
1033                         }
1034                   qDebug("Measure::remove: %s %p not found", e->name(), e);
1035                   break;
1036 
1037             case ElementType::MEASURE:
1038                   _mmRest = 0;
1039                   break;
1040 
1041             case ElementType::STAFFTYPE_CHANGE:
1042                   {
1043                   StaffTypeChange* stc = toStaffTypeChange(e);
1044                   Staff* staff = stc->staff();
1045                   if (staff) {
1046                         // st currently points to an list element that is about to be removed
1047                         // make a copy now to use on undo/redo
1048                         StaffType* st = new StaffType(*stc->staffType());
1049                         if (!tick().isZero())
1050                               staff->removeStaffType(tick());
1051                         stc->setStaffType(st);
1052                         }
1053                   MeasureBase::remove(e);
1054                   }
1055                   break;
1056 
1057             default:
1058                   MeasureBase::remove(e);
1059                   break;
1060             }
1061       }
1062 
1063 //---------------------------------------------------------
1064 //   change
1065 //---------------------------------------------------------
1066 
change(Element * o,Element * n)1067 void Measure::change(Element* o, Element* n)
1068       {
1069       if (o->isTuplet()) {
1070             Tuplet* t = toTuplet(n);
1071             for (DurationElement* e : t->elements())
1072                   e->setTuplet(t);
1073             }
1074       else {
1075             remove(o);
1076             add(n);
1077             }
1078       }
1079 
1080 //---------------------------------------------------------
1081 //   spatiumChanged
1082 //---------------------------------------------------------
1083 
spatiumChanged(qreal,qreal)1084 void Measure::spatiumChanged(qreal /*oldValue*/, qreal /*newValue*/)
1085       {
1086       }
1087 
1088 //-------------------------------------------------------------------
1089 //   moveTicks
1090 //    Also adjust endBarLine if measure len has changed. For this
1091 //    diff == 0 cannot be optimized away
1092 //-------------------------------------------------------------------
1093 
moveTicks(const Fraction & diff)1094 void Measure::moveTicks(const Fraction& diff)
1095       {
1096       std::set<Tuplet*> tuplets;
1097       setTick(tick() + diff);
1098       for (Segment* segment = last(); segment; segment = segment->prev()) {
1099             if (segment->segmentType() & (SegmentType::EndBarLine | SegmentType::TimeSigAnnounce))
1100                   segment->setRtick(ticks());
1101             else if (segment->isChordRestType()) {
1102                   // Tuplet ticks are stored as absolute ticks, so they must be adjusted.
1103                   // But each tuplet must only be adjusted once.
1104                   for (Element* e : segment->elist()) {
1105                         if (e) {
1106                               ChordRest* cr = toChordRest(e);
1107                               Tuplet* tuplet = cr->tuplet();
1108                               if (tuplet && tuplets.count(tuplet) == 0) {
1109                                     tuplet->setTick(tuplet->tick() + diff);
1110                                     tuplets.insert(tuplet);
1111                                     }
1112                               }
1113                         }
1114                   }
1115             }
1116       tuplets.clear();
1117       }
1118 
1119 //---------------------------------------------------------
1120 //   removeStaves
1121 //---------------------------------------------------------
1122 
removeStaves(int sStaff,int eStaff)1123 void Measure::removeStaves(int sStaff, int eStaff)
1124       {
1125       for (Segment* s = first(); s; s = s->next()) {
1126             for (int staff = eStaff-1; staff >= sStaff; --staff) {
1127                   s->removeStaff(staff);
1128                   }
1129             }
1130       for (Element* e : el()) {
1131             if (e->track() == -1)
1132                   continue;
1133             int voice = e->voice();
1134             int staffIdx = e->staffIdx();
1135             if (staffIdx >= eStaff) {
1136                   staffIdx -= eStaff - sStaff;
1137                   e->setTrack(staffIdx * VOICES + voice);
1138                   }
1139             }
1140       }
1141 
1142 //---------------------------------------------------------
1143 //   insertStaves
1144 //---------------------------------------------------------
1145 
insertStaves(int sStaff,int eStaff)1146 void Measure::insertStaves(int sStaff, int eStaff)
1147       {
1148       for (Element* e : el()) {
1149             if (e->track() == -1)
1150                   continue;
1151             int staffIdx = e->staffIdx();
1152             if (staffIdx >= sStaff && !e->systemFlag()) {
1153                   int voice = e->voice();
1154                   staffIdx += eStaff - sStaff;
1155                   e->setTrack(staffIdx * VOICES + voice);
1156                   }
1157             }
1158       for (Segment* s = first(); s; s = s->next()) {
1159             for (int staff = sStaff; staff < eStaff; ++staff) {
1160                   s->insertStaff(staff);
1161                   }
1162             }
1163       }
1164 
1165 //---------------------------------------------------------
1166 //   cmdRemoveStaves
1167 //---------------------------------------------------------
1168 
cmdRemoveStaves(int sStaff,int eStaff)1169 void Measure::cmdRemoveStaves(int sStaff, int eStaff)
1170       {
1171       int sTrack = sStaff * VOICES;
1172       int eTrack = eStaff * VOICES;
1173       for (Segment* s = first(); s; s = s->next()) {
1174             for (int track = eTrack - 1; track >= sTrack; --track) {
1175                   Element* el = s->element(track);
1176                   if (el) {
1177                         el->undoUnlink();
1178                         score()->undo(new RemoveElement(el));
1179                         }
1180                   }
1181             foreach (Element* e, s->annotations()) {
1182                   int staffIdx = e->staffIdx();
1183                   if ((staffIdx >= sStaff) && (staffIdx < eStaff) && !e->systemFlag()) {
1184                         e->undoUnlink();
1185                         score()->undo(new RemoveElement(e));
1186                         }
1187                   }
1188             }
1189       for (Element* e : el()) {
1190             if (e->track() == -1)
1191                   continue;
1192             int staffIdx = e->staffIdx();
1193             if (staffIdx >= sStaff && (staffIdx < eStaff) && !e->systemFlag()) {
1194                   e->undoUnlink();
1195                   score()->undo(new RemoveElement(e));
1196                   }
1197             }
1198 
1199       score()->undo(new RemoveStaves(this, sStaff, eStaff));
1200 
1201       for (int i = eStaff - 1; i >= sStaff; --i) {
1202             MStaff* ms = *(_mstaves.begin()+i);
1203             score()->undo(new RemoveMStaff(this, ms, i));
1204             }
1205 
1206       // barLine
1207       // TODO
1208       }
1209 
1210 //---------------------------------------------------------
1211 //   cmdAddStaves
1212 //---------------------------------------------------------
1213 
cmdAddStaves(int sStaff,int eStaff,bool createRest)1214 void Measure::cmdAddStaves(int sStaff, int eStaff, bool createRest)
1215       {
1216       score()->undo(new InsertStaves(this, sStaff, eStaff));
1217 
1218       Segment* ts = findSegment(SegmentType::TimeSig, tick());
1219       Segment* bs = findSegmentR(SegmentType::EndBarLine, ticks());
1220 
1221       for (int i = sStaff; i < eStaff; ++i) {
1222             Staff* staff = score()->staff(i);
1223             MStaff* ms   = new MStaff;
1224             ms->setLines(new StaffLines(score()));
1225             ms->lines()->setTrack(i * VOICES);
1226             ms->lines()->setParent(this);
1227             ms->lines()->setVisible(!staff->invisible(tick()));
1228             score()->undo(new InsertMStaff(this, ms, i));
1229             }
1230 
1231       if (!createRest && !ts)
1232             return;
1233 
1234 
1235       // create list of unique staves (only one instance for linked staves):
1236 
1237       QList<int> sl;
1238       for (int staffIdx = sStaff; staffIdx < eStaff; ++staffIdx) {
1239             Staff* s = score()->staff(staffIdx);
1240             if (s->links()) {
1241                   bool alreadyInList = false;
1242                   for (int idx : sl) {
1243                         if (s->links()->contains(score()->staff(idx))) {
1244                               alreadyInList = true;
1245                               break;
1246                               }
1247                         }
1248                   if (alreadyInList)
1249                         continue;
1250                   }
1251             sl.append(staffIdx);
1252             }
1253 
1254       for (int staffIdx : sl) {
1255             if (createRest)
1256                   score()->setRest(tick(), staffIdx * VOICES, ticks(), false, 0, _timesig == ticks());
1257 
1258             // replicate time signature
1259             if (ts) {
1260                   TimeSig* ots = 0;
1261                   bool constructed = false;
1262                   for (unsigned track = 0; track < _mstaves.size() * VOICES; ++track) {
1263                         if (ts->element(track)) {
1264                               ots = toTimeSig(ts->element(track));
1265                               break;
1266                               }
1267                         }
1268                   if (!ots) {
1269                         // no time signature found; use measure timesig to construct one
1270                         ots = new TimeSig(score());
1271                         ots->setSig(timesig());
1272                         constructed = true;
1273                         }
1274                   // do no replicate local time signatures
1275                   if (ots && !ots->isLocal()) {
1276                         TimeSig* timesig = new TimeSig(*ots);
1277                         timesig->setTrack(staffIdx * VOICES);
1278                         timesig->setParent(ts);
1279                         timesig->setSig(ots->sig(), ots->timeSigType());
1280                         score()->undoAddElement(timesig);
1281                         if (constructed)
1282                               delete ots;
1283                         }
1284                   }
1285 
1286             // replicate barline
1287             if (bs) {
1288                   BarLine* obl = nullptr;
1289                   for (unsigned track = 0; track < _mstaves.size() * VOICES; ++track) {
1290                         Element* e = bs->element(track);
1291                         if (e && !e->generated()) {
1292                               obl = toBarLine(e);
1293                               break;
1294                               }
1295                         }
1296                   if (obl) {
1297                         BarLine* barline = new BarLine(*obl);
1298                         barline->setSpanStaff(score()->staff(staffIdx)->barLineSpan());
1299                         barline->setTrack(staffIdx * VOICES);
1300                         barline->setParent(bs);
1301                         barline->setGenerated(false);
1302                         score()->undoAddElement(barline);
1303                         }
1304                   }
1305             }
1306       }
1307 
1308 //---------------------------------------------------------
1309 //   insertMStaff
1310 //---------------------------------------------------------
1311 
insertMStaff(MStaff * staff,int idx)1312 void Measure::insertMStaff(MStaff* staff, int idx)
1313       {
1314       _mstaves.insert(_mstaves.begin()+idx, staff);
1315       for (unsigned staffIdx = 0; staffIdx < _mstaves.size(); ++staffIdx)
1316             _mstaves[staffIdx]->setTrack(staffIdx * VOICES);
1317       }
1318 
1319 //---------------------------------------------------------
1320 //   removeMStaff
1321 //---------------------------------------------------------
1322 
removeMStaff(MStaff *,int idx)1323 void Measure::removeMStaff(MStaff* /*staff*/, int idx)
1324       {
1325       _mstaves.erase(_mstaves.begin()+idx);
1326       for (unsigned staffIdx = 0; staffIdx < _mstaves.size(); ++staffIdx)
1327             _mstaves[staffIdx]->setTrack(staffIdx * VOICES);
1328       }
1329 
1330 //---------------------------------------------------------
1331 //   insertStaff
1332 //---------------------------------------------------------
1333 
insertStaff(Staff * staff,int staffIdx)1334 void Measure::insertStaff(Staff* staff, int staffIdx)
1335       {
1336       for (Segment* s = first(); s; s = s->next())
1337             s->insertStaff(staffIdx);
1338 
1339       MStaff* ms = new MStaff;
1340       ms->setLines(new StaffLines(score()));
1341       ms->lines()->setParent(this);
1342       ms->lines()->setTrack(staffIdx * VOICES);
1343       ms->lines()->setVisible(!staff->invisible(tick()));
1344       insertMStaff(ms, staffIdx);
1345       }
1346 
1347 //---------------------------------------------------------
1348 //   staffabbox
1349 //---------------------------------------------------------
1350 
staffabbox(int staffIdx) const1351 QRectF Measure::staffabbox(int staffIdx) const
1352       {
1353       System* s = system();
1354       QRectF sb(s->staff(staffIdx)->bbox());
1355       QRectF rrr(sb.translated(s->pagePos()));
1356       QRectF rr(abbox());
1357       QRectF r(rr.x(), rrr.y(), rr.width(), rrr.height());
1358       return r;
1359       }
1360 
1361 //---------------------------------------------------------
1362 //   acceptDrop
1363 //---------------------------------------------------------
1364 
1365 /**
1366  Return true if an Element of type \a type can be dropped on a Measure
1367 */
1368 
acceptDrop(EditData & data) const1369 bool Measure::acceptDrop(EditData& data) const
1370       {
1371       MuseScoreView* viewer = data.view;
1372       QPointF pos           = data.pos;
1373       Element* e            = data.dropElement;
1374 
1375       int staffIdx;
1376       Segment* seg;
1377       if (!score()->pos2measure(pos, &staffIdx, 0, &seg, 0))
1378             return false;
1379 
1380       QRectF staffR = system()->staff(staffIdx)->bbox().translated(system()->canvasPos());
1381       staffR &= canvasBoundingRect();
1382 
1383       switch (e->type()) {
1384             case ElementType::MEASURE_LIST:
1385             case ElementType::JUMP:
1386             case ElementType::MARKER:
1387             case ElementType::LAYOUT_BREAK:
1388             case ElementType::STAFF_LIST:
1389                   viewer->setDropRectangle(canvasBoundingRect());
1390                   return true;
1391 
1392             case ElementType::KEYSIG:
1393             case ElementType::TIMESIG:
1394                   if (data.modifiers & Qt::ControlModifier)
1395                         viewer->setDropRectangle(staffR);
1396                   else
1397                         viewer->setDropRectangle(canvasBoundingRect());
1398                   return true;
1399 
1400             case ElementType::MEASURE_NUMBER:
1401                   viewer->setDropRectangle(canvasBoundingRect());
1402                   return true;
1403 
1404             case ElementType::BRACKET:
1405             case ElementType::REPEAT_MEASURE:
1406             case ElementType::MEASURE:
1407             case ElementType::SPACER:
1408             case ElementType::IMAGE:
1409             case ElementType::BAR_LINE:
1410             case ElementType::SYMBOL:
1411             case ElementType::CLEF:
1412             case ElementType::STAFFTYPE_CHANGE:
1413                   viewer->setDropRectangle(staffR);
1414                   return true;
1415 
1416             case ElementType::ICON:
1417                   switch (toIcon(e)->iconType()) {
1418                         case IconType::VFRAME:
1419                         case IconType::HFRAME:
1420                         case IconType::TFRAME:
1421                         case IconType::FFRAME:
1422                         case IconType::MEASURE:
1423                               viewer->setDropRectangle(canvasBoundingRect());
1424                               return true;
1425                         default:
1426                               break;
1427                         }
1428                   break;
1429 
1430             default:
1431                   break;
1432             }
1433       return false;
1434       }
1435 
1436 //---------------------------------------------------------
1437 //   drop
1438 ///   Drop element.
1439 ///   Handle a dropped element at position \a pos of given
1440 ///   element \a type and \a subtype.
1441 //---------------------------------------------------------
1442 
drop(EditData & data)1443 Element* Measure::drop(EditData& data)
1444       {
1445       Element* e = data.dropElement;
1446       int staffIdx = -1;
1447       Segment* seg;
1448       score()->pos2measure(data.pos, &staffIdx, 0, &seg, 0);
1449 
1450       if (e->systemFlag())
1451             staffIdx = 0;
1452       if (staffIdx < 0)
1453             return 0;
1454       Staff* staff = score()->staff(staffIdx);
1455       //bool fromPalette = (e->track() == -1);
1456 
1457       switch (e->type()) {
1458             case ElementType::MEASURE_LIST:
1459                   delete e;
1460                   break;
1461 
1462             case ElementType::STAFF_LIST:
1463 //TODO                  score()->pasteStaff(e, this, staffIdx);
1464                   delete e;
1465                   break;
1466 
1467             case ElementType::MARKER:
1468             case ElementType::JUMP:
1469                   e->setParent(this);
1470                   e->setTrack(0);
1471                   score()->undoAddElement(e);
1472                   return e;
1473 
1474             case ElementType::DYNAMIC:
1475             case ElementType::FRET_DIAGRAM:
1476                   e->setParent(seg);
1477                   e->setTrack(staffIdx * VOICES);
1478                   score()->undoAddElement(e);
1479                   return e;
1480 
1481             case ElementType::IMAGE:
1482             case ElementType::SYMBOL:
1483                   e->setParent(seg);
1484                   e->setTrack(staffIdx * VOICES);
1485                   e->layout();
1486                   {
1487                   QPointF uo(data.pos - e->canvasPos() - data.dragOffset);
1488                   e->setOffset(uo);
1489                   }
1490                   score()->undoAddElement(e);
1491                   return e;
1492 
1493             case ElementType::MEASURE_NUMBER:
1494                   undoChangeProperty(Pid::MEASURE_NUMBER_MODE, static_cast<int>(MeasureNumberMode::SHOW));
1495                   delete e;
1496                   break;
1497 
1498             case ElementType::BRACKET:
1499                   {
1500                   Bracket* b = toBracket(e);
1501                   int level = 0;
1502                   int firstStaff = 0;
1503                   for (Staff* s : score()->staves()) {
1504                         for (const BracketItem* bi : s->brackets()) {
1505                               int lastStaff = firstStaff + bi->bracketSpan() - 1;
1506                               if (staffIdx >= firstStaff && staffIdx <= lastStaff)
1507                                     ++level;
1508                               }
1509                         firstStaff++;
1510                         }
1511                   Selection sel = score()->selection();
1512                   if (sel.isRange())
1513                         score()->undoAddBracket(staff, level, b->bracketType(), sel.staffEnd() - sel.staffStart());
1514                   else
1515                         score()->undoAddBracket(staff, level, b->bracketType(), 1);
1516                   delete b;
1517                   }
1518                   break;
1519 
1520             case ElementType::CLEF:
1521                   score()->undoChangeClef(staff, this, toClef(e)->clefType());
1522                   delete e;
1523                   break;
1524 
1525             case ElementType::KEYSIG:
1526                   {
1527                   KeySigEvent k = toKeySig(e)->keySigEvent();
1528                   delete e;
1529 
1530                   if (data.modifiers & Qt::ControlModifier) {
1531                         // apply only to this stave
1532                         score()->undoChangeKeySig(staff, tick(), k);
1533                         }
1534                   else {
1535                         // apply to all staves:
1536                         for (Staff* s : score()->staves())
1537                               score()->undoChangeKeySig(s, tick(), k);
1538                         }
1539 
1540                   break;
1541                   }
1542 
1543             case ElementType::TIMESIG:
1544                   score()->cmdAddTimeSig(this, staffIdx, toTimeSig(e), data.modifiers & Qt::ControlModifier);
1545                   break;
1546 
1547             case ElementType::LAYOUT_BREAK: {
1548                   LayoutBreak* b = toLayoutBreak(e);
1549                   Measure* measure = isMMRest() ? mmRestLast() : this;
1550                   switch (b->layoutBreakType()) {
1551                         case  LayoutBreak::PAGE:
1552                               if (measure->pageBreak()) {
1553                                     delete b;
1554                                     b = 0;
1555                                     }
1556                               else
1557                                     measure->setLineBreak(false);
1558                               break;
1559                         case  LayoutBreak::LINE:
1560                               if (measure->lineBreak()) {
1561                                     delete b;
1562                                     b = 0;
1563                                     }
1564                               else
1565                                     measure->setPageBreak(false);
1566                               break;
1567                         case  LayoutBreak::SECTION:
1568                               if (measure->sectionBreak()) {
1569                                     delete b;
1570                                     b = 0;
1571                                     }
1572                               else
1573                                     measure->setLineBreak(false);
1574                               break;
1575                         case LayoutBreak::NOBREAK:
1576                               if (measure->noBreak()) {
1577                                     delete b;
1578                                     b = 0;
1579                                     }
1580                               else {
1581                                     measure->setLineBreak(false);
1582                                     measure->setPageBreak(false);
1583                                     }
1584                               break;
1585                         }
1586                   if (b) {
1587                         b->setTrack(-1);       // these are system elements
1588                         b->setParent(measure);
1589                         score()->undoAddElement(b);
1590                         }
1591                   measure->cleanupLayoutBreaks(true);
1592                   return b;
1593                   }
1594 
1595             case ElementType::SPACER:
1596                   {
1597                   Spacer* spacer = toSpacer(e);
1598                   spacer->setTrack(staffIdx * VOICES);
1599                   spacer->setParent(this);
1600                   if (spacer->spacerType() == SpacerType::FIXED) {
1601                         qreal gap = spatium() * 10;
1602                         System* s = system();
1603                         const int nextVisStaffIdx = s->nextVisibleStaff(staffIdx);
1604                         const bool systemEnd = (nextVisStaffIdx == score()->nstaves());
1605                         if (systemEnd) {
1606                               System* ns = 0;
1607                               for (System* ts : score()->systems()) {
1608                                     if (ns) {
1609                                           ns = ts;
1610                                           break;
1611                                           }
1612                                     if (ts  == s)
1613                                           ns = ts;
1614                                     }
1615                               if (ns && ns->page() == s->page()) {
1616                                     qreal y1 = s->staffYpage(staffIdx);
1617                                     qreal y2 = ns->staffYpage(0);
1618                                     gap = y2 - y1 - score()->staff(staffIdx)->height();
1619                                     }
1620                               }
1621                         else {
1622                               qreal y1 = s->staffYpage(staffIdx);
1623                               qreal y2 = s->staffYpage(nextVisStaffIdx);
1624                               gap = y2 - y1 - score()->staff(staffIdx)->height();
1625                               }
1626                         spacer->setGap(gap);
1627                         }
1628                   score()->undoAddElement(spacer);
1629                   triggerLayout();
1630                   return spacer;
1631                   }
1632 
1633             case ElementType::BAR_LINE:
1634                   {
1635                   BarLine* bl = toBarLine(e);
1636 
1637                   // if dropped bar line refers to span rather than to subtype
1638                   // or if Ctrl key used
1639                   if ((bl->spanFrom() && bl->spanTo()) || data.control()) {
1640                         // get existing bar line for this staff, and drop the change to it
1641                         seg = undoGetSegmentR(SegmentType::EndBarLine, ticks());
1642                         BarLine* cbl = toBarLine(seg->element(staffIdx * VOICES));
1643                         if (cbl)
1644                               cbl->drop(data);
1645                         }
1646                   else if (bl->barLineType() == BarLineType::START_REPEAT) {
1647                         Measure* m2 = isMMRest() ? mmRestFirst() : this;
1648                         for (Score* lscore : score()->scoreList()) {
1649                               Measure* lmeasure = lscore->tick2measure(m2->tick());
1650                               if (lmeasure)
1651                                     lmeasure->undoChangeProperty(Pid::REPEAT_START, true);
1652                               }
1653                         }
1654                   else if (bl->barLineType() == BarLineType::END_REPEAT) {
1655                         Measure* m2 = isMMRest() ? mmRestLast() : this;
1656                         for (Score* lscore : score()->scoreList()) {
1657                               Measure* lmeasure = lscore->tick2measure(m2->tick());
1658                               if (lmeasure)
1659                                     lmeasure->undoChangeProperty(Pid::REPEAT_END, true);
1660                               }
1661                         }
1662                   else if (bl->barLineType() == BarLineType::END_START_REPEAT) {
1663                         Measure* m2 = isMMRest() ? mmRestLast() : this;
1664                         for (Score* lscore : score()->scoreList()) {
1665                               Measure* lmeasure = lscore->tick2measure(m2->tick());
1666                               if (lmeasure) {
1667                                     lmeasure->undoChangeProperty(Pid::REPEAT_END, true);
1668                                     lmeasure = lmeasure->nextMeasure();
1669                                     if (lmeasure)
1670                                           lmeasure->undoChangeProperty(Pid::REPEAT_START, true);
1671                                     }
1672                               }
1673                         }
1674                   else {
1675                         // drop to first end barline
1676                         seg = findSegmentR(SegmentType::EndBarLine, ticks());
1677                         if (seg) {
1678                               for (Element* ee : seg->elist()) {
1679                                     if (ee) {
1680                                           ee->drop(data);
1681                                           break;
1682                                           }
1683                                     }
1684                               }
1685                         else
1686                               delete e;
1687                         }
1688                   break;
1689                   }
1690 
1691             case ElementType::REPEAT_MEASURE:
1692                   {
1693                   delete e;
1694                   return cmdInsertRepeatMeasure(staffIdx);
1695                   }
1696             case ElementType::ICON:
1697                   switch(toIcon(e)->iconType()) {
1698                         case IconType::VFRAME:
1699                               score()->insertMeasure(ElementType::VBOX, this);
1700                               break;
1701                         case IconType::HFRAME:
1702                               score()->insertMeasure(ElementType::HBOX, this);
1703                               break;
1704                         case IconType::TFRAME:
1705                               score()->insertMeasure(ElementType::TBOX, this);
1706                               break;
1707                         case IconType::FFRAME:
1708                               score()->insertMeasure(ElementType::FBOX, this);
1709                               break;
1710                         case IconType::MEASURE:
1711                               score()->insertMeasure(ElementType::MEASURE, this);
1712                               break;
1713                         default:
1714                               break;
1715                         }
1716                   break;
1717 
1718             case ElementType::STAFFTYPE_CHANGE:
1719                   {
1720                   e->setParent(this);
1721                   e->setTrack(staffIdx * VOICES);
1722                   score()->undoAddElement(e);
1723                   }
1724                   break;
1725 
1726             default:
1727                   qDebug("Measure: cannot drop %s here", e->name());
1728                   delete e;
1729                   break;
1730             }
1731       return 0;
1732       }
1733 
1734 //---------------------------------------------------------
1735 //   cmdInsertRepeatMeasure
1736 //---------------------------------------------------------
1737 
cmdInsertRepeatMeasure(int staffIdx)1738 RepeatMeasure* Measure::cmdInsertRepeatMeasure(int staffIdx)
1739       {
1740       //
1741       // see also cmdDeleteSelection()
1742       //
1743       score()->select(0, SelectType::SINGLE, 0);
1744       for (Segment* s = first(); s; s = s->next()) {
1745             if (s->segmentType() & SegmentType::ChordRest) {
1746                   int strack = staffIdx * VOICES;
1747                   int etrack = strack + VOICES;
1748                   for (int track = strack; track < etrack; ++track) {
1749                         Element* el = s->element(track);
1750                         if (el)
1751                               score()->undoRemoveElement(el);
1752                         }
1753                   }
1754             }
1755       //
1756       // add repeat measure
1757       //
1758       Segment* seg = undoGetSegment(SegmentType::ChordRest, tick());
1759       RepeatMeasure* rm = new RepeatMeasure(score());
1760       rm->setTrack(staffIdx * VOICES);
1761       rm->setParent(seg);
1762       rm->setDurationType(TDuration::DurationType::V_MEASURE);
1763       rm->setTicks(stretchedLen(score()->staff(staffIdx)));
1764       score()->undoAddCR(rm, this, tick());
1765       for (Element* e : el()) {
1766             if (e->isSlur() && e->staffIdx() == staffIdx)
1767                   score()->undoRemoveElement(e);
1768             }
1769       return rm;
1770       }
1771 
1772 //---------------------------------------------------------
1773 //   adjustToLen
1774 //    change actual measure len, adjust elements to
1775 //    new len
1776 //---------------------------------------------------------
1777 
adjustToLen(Fraction nf,bool appendRestsIfNecessary)1778 void Measure::adjustToLen(Fraction nf, bool appendRestsIfNecessary)
1779       {
1780       Fraction ol   = ticks();
1781       Fraction nl   = nf;
1782       Fraction diff = nl - ol;
1783 
1784       Fraction startTick = endTick();
1785       if (diff < Fraction(0,1))
1786             startTick += diff;
1787 
1788       score()->undoInsertTime(startTick, diff);
1789       score()->undo(new InsertTime(score(), startTick, diff));
1790 
1791       for (Score* s : score()->scoreList()) {
1792             Measure* m = s->tick2measure(tick());
1793             s->undo(new ChangeMeasureLen(m, nf));
1794             if (nl > ol) {
1795                   // move EndBarLine, TimeSigAnnounce, KeySigAnnounce
1796                   for (Segment* seg = m->first(); seg; seg = seg->next()) {
1797                         if (seg->segmentType() & (SegmentType::EndBarLine|SegmentType::TimeSigAnnounce|SegmentType::KeySigAnnounce)) {
1798                               seg->setRtick(nl);
1799                               }
1800                         }
1801                   }
1802             }
1803       Score* s      = score()->masterScore();
1804       Measure* m    = s->tick2measure(tick());
1805       QList<int> sl = s->uniqueStaves();
1806 
1807       for (int staffIdx : qAsConst(sl)) {
1808             int rests  = 0;
1809             int chords = 0;
1810             Rest* rest = 0;
1811             for (Segment* segment = m->first(); segment; segment = segment->next()) {
1812                   int strack = staffIdx * VOICES;
1813                   int etrack = strack + VOICES;
1814                   for (int track = strack; track < etrack; ++track) {
1815                         Element* e = segment->element(track);
1816                         if (e) {
1817                               if (e->isRest()) {
1818                                     ++rests;
1819                                     rest = toRest(e);
1820                                     }
1821                               else if (e->isChord())
1822                                     ++chords;
1823                               }
1824                         }
1825                   }
1826             Fraction stretch = s->staff(staffIdx)->timeStretch(tick());
1827             // if just a single rest
1828             if (rests == 1 && chords == 0) {
1829                   // if measure value didn't change, stick to whole measure rest
1830                   if (_timesig == nf) {
1831                         rest->undoChangeProperty(Pid::DURATION, QVariant::fromValue<Fraction>(nf * stretch));
1832                         rest->undoChangeProperty(Pid::DURATION_TYPE, QVariant::fromValue<TDuration>(TDuration::DurationType::V_MEASURE));
1833                         }
1834                   else {      // if measure value did change, represent with rests actual measure value
1835 #if 0
1836                         // any reason not to do this instead?
1837                         s->undoRemoveElement(rest);
1838                         s->setRest(tick(), staffIdx * VOICES, nf * stretch, false, 0, false);
1839 #else
1840                         // convert the measure duration in a list of values (no dots for rests)
1841                         std::vector<TDuration> durList = toDurationList(nf * stretch, false, 0);
1842 
1843                         // set the existing rest to the first value of the duration list
1844                         for (ScoreElement* e : rest->linkList()) {
1845                               e->undoChangeProperty(Pid::DURATION, QVariant::fromValue<Fraction>(durList[0].fraction()));
1846                               e->undoChangeProperty(Pid::DURATION_TYPE, QVariant::fromValue<TDuration>(durList[0]));
1847                               }
1848 
1849                         // add rests for any other duration list value
1850                         Fraction tickOffset = tick() + rest->actualTicks();
1851                         for (unsigned i = 1; i < durList.size(); i++) {
1852                               Rest* newRest = new Rest(s);
1853                               newRest->setDurationType(durList.at(i));
1854                               newRest->setTicks(durList.at(i).fraction());
1855                               newRest->setTrack(rest->track());
1856                               score()->undoAddCR(newRest, this, tickOffset);
1857                               tickOffset += newRest->actualTicks();
1858                               }
1859 #endif
1860                         }
1861                   continue;
1862                   }
1863 
1864             int strack = staffIdx * VOICES;
1865             int etrack = strack + VOICES;
1866 
1867             for (int trk = strack; trk < etrack; ++trk) {
1868                   Fraction n = diff;
1869                   bool rFlag = false;
1870                   if (n < Fraction(0,1))  {
1871                         for (Segment* segment = m->last(); segment;) {
1872                               Segment* pseg = segment->prev();
1873                               if (segment->segmentType() == SegmentType::ChordRest) {
1874                                     for (Element* a : segment->annotations())
1875                                           if (a->track() == trk)
1876                                                 s->undoRemoveElement(a);
1877                                     Element* e = segment->element(trk);
1878                                     if (e && e->isChordRest()) {
1879                                           ChordRest* cr = toChordRest(e);
1880                                           if (cr->durationType() == TDuration::DurationType::V_MEASURE) {
1881                                                 Fraction actualTicks = cr->actualTicks();
1882                                                 n += actualTicks;
1883                                                 cr->setDurationType(TDuration(actualTicks));
1884                                                 }
1885                                           else
1886                                                 n += cr->actualTicks();
1887                                           s->undoRemoveElement(e);
1888                                           if (n >= Fraction(0,1))
1889                                                 break;
1890                                           }
1891                                     }
1892                               else if (segment->segmentType() == SegmentType::Breath) {
1893                                     Element* e = segment->element(trk);
1894                                     if (e)
1895                                           s->undoRemoveElement(e);
1896                                     }
1897                               segment = pseg;
1898                               }
1899                         rFlag = true;
1900                         }
1901                   int voice = trk % VOICES;
1902                   if (appendRestsIfNecessary && (n > Fraction(0,1)) && (rFlag || voice == 0)) {
1903                         // add rest to measure
1904                         Fraction rtick = tick() + nl - n;
1905                         int track = staffIdx * VOICES + voice;
1906                         s->setRest(rtick, track, n * stretch, false, 0, false);
1907                         }
1908                   }
1909             }
1910       if (diff < Fraction(0,1)) {
1911             //
1912             //  CHECK: do not remove all slurs
1913             //
1914             for (Element* e : m->el()) {
1915                   if (e->isSlur())
1916                         s->undoRemoveElement(e);
1917                   }
1918             }
1919       }
1920 
1921 //---------------------------------------------------------
1922 //   write
1923 //---------------------------------------------------------
1924 
write(XmlWriter & xml,int staff,bool writeSystemElements,bool forceTimeSig) const1925 void Measure::write(XmlWriter& xml, int staff, bool writeSystemElements, bool forceTimeSig) const
1926       {
1927       if (MScore::debugMode) {
1928             const int mno = no() + 1;
1929             xml.comment(QString("Measure %1").arg(mno));
1930             }
1931       if (_len != _timesig) {
1932             // this is an irregular measure
1933             xml.stag(this, QString("len=\"%1/%2\"").arg(_len.numerator()).arg(_len.denominator()));
1934             }
1935       else
1936             xml.stag(this);
1937 
1938       xml.setCurTick(tick());
1939       xml.setCurTrack(staff * VOICES);
1940 
1941       if (_mmRestCount > 0)
1942             xml.tag("multiMeasureRest", _mmRestCount);
1943       if (writeSystemElements) {
1944             if (repeatStart())
1945                   xml.tagE("startRepeat");
1946             if (repeatEnd())
1947                   xml.tag("endRepeat", _repeatCount);
1948             writeProperty(xml, Pid::IRREGULAR);
1949             writeProperty(xml, Pid::BREAK_MMR);
1950             writeProperty(xml, Pid::USER_STRETCH);
1951             writeProperty(xml, Pid::NO_OFFSET);
1952             writeProperty(xml, Pid::MEASURE_NUMBER_MODE);
1953             }
1954       qreal _spatium = spatium();
1955       MStaff* mstaff = _mstaves[staff];
1956       if (mstaff->noText() && !mstaff->noText()->generated())
1957             mstaff->noText()->write(xml);
1958 
1959       if (mstaff->mmRangeText() && !mstaff->mmRangeText()->generated())
1960             mstaff->mmRangeText()->write(xml);
1961 
1962       if (mstaff->vspacerUp())
1963             xml.tag("vspacerUp", mstaff->vspacerUp()->gap() / _spatium);
1964       if (mstaff->vspacerDown()) {
1965             if (mstaff->vspacerDown()->spacerType() == SpacerType::FIXED)
1966                   xml.tag("vspacerFixed", mstaff->vspacerDown()->gap() / _spatium);
1967             else
1968                   xml.tag("vspacerDown", mstaff->vspacerDown()->gap() / _spatium);
1969             }
1970       if (!mstaff->visible())
1971             xml.tag("visible", mstaff->visible());
1972       if (mstaff->stemless()) {
1973             xml.tag("slashStyle", mstaff->stemless()); // for backwards compatibility
1974             xml.tag("stemless", mstaff->stemless());
1975             }
1976 
1977       int strack = staff * VOICES;
1978       int etrack = strack + VOICES;
1979       for (const Element* e : el()) {
1980             if (!e->generated() && ((e->staffIdx() == staff) || (e->systemFlag() && writeSystemElements)))
1981                   e->write(xml);
1982             }
1983       Q_ASSERT(first());
1984       Q_ASSERT(last());
1985       if (first() && last())
1986             score()->writeSegments(xml, strack, etrack, first(), last()->next1(), writeSystemElements, forceTimeSig);
1987 
1988       xml.etag();
1989       }
1990 
1991 //---------------------------------------------------------
1992 //   Measure::read
1993 //---------------------------------------------------------
1994 
read(XmlReader & e,int staffIdx)1995 void Measure::read(XmlReader& e, int staffIdx)
1996       {
1997       qreal _spatium = spatium();
1998       e.setCurrentMeasure(this);
1999       int nextTrack = staffIdx * VOICES;
2000       e.setTrack(nextTrack);
2001 
2002       for (int n = int(_mstaves.size()); n <= staffIdx; ++n) {
2003             Staff* staff = score()->staff(n);
2004             MStaff* s    = new MStaff;
2005             s->setLines(new StaffLines(score()));
2006             s->lines()->setParent(this);
2007             s->lines()->setTrack(n * VOICES);
2008             s->lines()->setVisible(!staff->invisible(tick()));
2009             _mstaves.push_back(s);
2010             }
2011 
2012       bool irregular;
2013       if (e.hasAttribute("len")) {
2014             QStringList sl = e.attribute("len").split('/');
2015             if (sl.size() == 2)
2016                   _len = Fraction(sl[0].toInt(), sl[1].toInt());
2017             else
2018                   qDebug("illegal measure size <%s>", qPrintable(e.attribute("len")));
2019             irregular = true;
2020             if (_len.numerator() <= 0 || _len.denominator() <= 0) {
2021                   e.raiseError(QObject::tr("MSCX error at line %1: invalid measure length: %2").arg(e.lineNumber()).arg(_len.toString()));
2022                   return;
2023                   }
2024             score()->sigmap()->add(tick().ticks(), SigEvent(_len, _timesig));
2025             score()->sigmap()->add((tick() + ticks()).ticks(), SigEvent(_timesig));
2026             }
2027       else
2028             irregular = false;
2029 
2030       while (e.readNextStartElement()) {
2031             const QStringRef& tag(e.name());
2032 
2033             if (tag == "voice") {
2034                   e.setTrack(nextTrack++);
2035                   e.setTick(tick());
2036                   readVoice(e, staffIdx, irregular);
2037                   }
2038             else if (tag == "Marker" || tag == "Jump") {
2039                   Element* el = Element::name2Element(tag, score());
2040                   el->setTrack(e.track());
2041                   el->read(e);
2042                   add(el);
2043                   }
2044             else if (tag == "stretch") {
2045                   double val = e.readDouble();
2046                   if (val < 0.0)
2047                         val = 0;
2048                   setUserStretch(val);
2049                   }
2050             else if (tag == "noOffset")
2051                   setNoOffset(e.readInt());
2052             else if (tag == "measureNumberMode")
2053                   setMeasureNumberMode(MeasureNumberMode(e.readInt()));
2054             else if (tag == "irregular")
2055                   setIrregular(e.readBool());
2056             else if (tag == "breakMultiMeasureRest")
2057                   _breakMultiMeasureRest = e.readBool();
2058             else if (tag == "startRepeat") {
2059                   setRepeatStart(true);
2060                   e.readNext();
2061                   }
2062             else if (tag == "endRepeat") {
2063                   _repeatCount = e.readInt();
2064                   setRepeatEnd(true);
2065                   }
2066             else if (tag == "vspacer" || tag == "vspacerDown") {
2067                   if (!_mstaves[staffIdx]->vspacerDown()) {
2068                         Spacer* spacer = new Spacer(score());
2069                         spacer->setSpacerType(SpacerType::DOWN);
2070                         spacer->setTrack(staffIdx * VOICES);
2071                         add(spacer);
2072                         }
2073                   _mstaves[staffIdx]->vspacerDown()->setGap(e.readDouble() * _spatium);
2074                   }
2075             else if (tag == "vspacerFixed") {
2076                   if (!_mstaves[staffIdx]->vspacerDown()) {
2077                         Spacer* spacer = new Spacer(score());
2078                         spacer->setSpacerType(SpacerType::FIXED);
2079                         spacer->setTrack(staffIdx * VOICES);
2080                         add(spacer);
2081                         }
2082                   _mstaves[staffIdx]->vspacerDown()->setGap(e.readDouble() * _spatium);
2083                   }
2084             else if (tag == "vspacerUp") {
2085                   if (!_mstaves[staffIdx]->vspacerUp()) {
2086                         Spacer* spacer = new Spacer(score());
2087                         spacer->setSpacerType(SpacerType::UP);
2088                         spacer->setTrack(staffIdx * VOICES);
2089                         add(spacer);
2090                         }
2091                   _mstaves[staffIdx]->vspacerUp()->setGap(e.readDouble() * _spatium);
2092                   }
2093             else if (tag == "visible")
2094                   _mstaves[staffIdx]->setVisible(e.readInt());
2095             else if ((tag == "slashStyle") || (tag == "stemless"))
2096                   _mstaves[staffIdx]->setStemless(e.readInt());
2097             else if (tag == "SystemDivider") {
2098                   SystemDivider* sd = new SystemDivider(score());
2099                   sd->read(e);
2100                   add(sd);
2101                   }
2102             else if (tag == "multiMeasureRest") {
2103                   _mmRestCount = e.readInt();
2104                   // set tick to previous measure
2105                   setTick(e.lastMeasure()->tick());
2106                   e.setTick(e.lastMeasure()->tick());
2107                   }
2108             else if (tag == "MeasureNumber") {
2109                   MeasureNumber* noText = new MeasureNumber(score());
2110                   noText->read(e);
2111                   noText->setTrack(e.track());
2112                   add(noText);
2113                   }
2114             else if (tag == "MMRestRange") {
2115                   MMRestRange* range = new MMRestRange(score());
2116                   range->read(e);
2117                   range->setTrack(e.track());
2118                   add(range);
2119                   }
2120             else if (MeasureBase::readProperties(e))
2121                   ;
2122             else
2123                   e.unknown();
2124             }
2125       e.checkConnectors();
2126       if (isMMRest()) {
2127             Measure* lm = e.lastMeasure();
2128             e.setTick(lm->tick() + lm->ticks());
2129             }
2130       e.setCurrentMeasure(nullptr);
2131 
2132       connectTremolo();
2133       }
2134 
2135 //---------------------------------------------------------
2136 //   Measure::readVoice
2137 //---------------------------------------------------------
2138 
readVoice(XmlReader & e,int staffIdx,bool irregular)2139 void Measure::readVoice(XmlReader& e, int staffIdx, bool irregular)
2140       {
2141       Segment* segment = nullptr;
2142       QList<Chord*> graceNotes;
2143       Beam* startingBeam = nullptr;
2144       Tuplet* tuplet = nullptr;
2145       Fermata* fermata = nullptr;
2146 
2147       Staff* staff = score()->staff(staffIdx);
2148       Fraction timeStretch(staff->timeStretch(tick()));
2149 
2150       while (e.readNextStartElement()) {
2151             const QStringRef& tag(e.name());
2152 
2153             if (tag == "location") {
2154                   Location loc = Location::relative();
2155                   loc.read(e);
2156                   e.setLocation(loc);
2157                   }
2158             else if (tag == "tick") {           // obsolete?
2159                   qDebug("read midi tick");
2160                   e.setTick(Fraction::fromTicks(score()->fileDivision(e.readInt())));
2161                   }
2162             else if (tag == "BarLine") {
2163                   BarLine* barLine = new BarLine(score());
2164                   barLine->setTrack(e.track());
2165                   barLine->read(e);
2166                   //
2167                   //  StartRepeatBarLine: at rtick == 0, always BarLineType::START_REPEAT
2168                   //  BarLine:            in the middle of a measure, has no semantic
2169                   //  EndBarLine:         at the end of a measure
2170                   //  BeginBarLine:       first segment of a measure, systemic barline
2171 
2172                   SegmentType st = SegmentType::Invalid;
2173                   Fraction t = e.tick() - tick();
2174                   if (t.isNotZero() && (t != ticks()))
2175                         st = SegmentType::BarLine;
2176                   else if (barLine->barLineType() == BarLineType::START_REPEAT && t.isZero())
2177                         st = SegmentType::StartRepeatBarLine;
2178                   else if (barLine->barLineType() == BarLineType::START_REPEAT && t == ticks()) {
2179                         // old version, ignore
2180                         delete barLine;
2181                         barLine = 0;
2182                         }
2183                   else if (t.isZero() && segment == 0)
2184                         st = SegmentType::BeginBarLine;
2185                   else
2186                         st = SegmentType::EndBarLine;
2187                   if (barLine) {
2188                         segment = getSegmentR(st, t);
2189                         segment->add(barLine);
2190                         barLine->layout();
2191                         }
2192                   if (fermata) {
2193                         segment->add(fermata);
2194                         fermata = nullptr;
2195                         }
2196                   }
2197             else if (tag == "Chord") {
2198                   Chord* chord = new Chord(score());
2199                   chord->setTrack(e.track());
2200                   chord->read(e);
2201                   if (startingBeam) {
2202                         startingBeam->add(chord); // also calls chord->setBeam(startingBeam)
2203                         startingBeam = nullptr;
2204                         }
2205 //                  if (tuplet && !chord->isGrace())
2206 //                        chord->readAddTuplet(tuplet);
2207                   segment = getSegment(SegmentType::ChordRest, e.tick());
2208                   if (chord->noteType() != NoteType::NORMAL)
2209                         graceNotes.push_back(chord);
2210                   else {
2211                         segment->add(chord);
2212                         for (int i = 0; i < graceNotes.size(); ++i) {
2213                               Chord* gc = graceNotes[i];
2214                               gc->setGraceIndex(i);
2215                               chord->add(gc);
2216                               }
2217                         graceNotes.clear();
2218                         if (tuplet)
2219                               tuplet->add(chord);
2220                         e.incTick(chord->actualTicks());
2221                         }
2222                   if (fermata) {
2223                         segment->add(fermata);
2224                         fermata = nullptr;
2225                         }
2226                   }
2227             else if (tag == "Rest") {
2228                   Rest* rest = new Rest(score());
2229                   rest->setDurationType(TDuration::DurationType::V_MEASURE);
2230                   rest->setTicks(timesig()/timeStretch);
2231                   rest->setTrack(e.track());
2232                   rest->read(e);
2233                   if (startingBeam) {
2234                         startingBeam->add(rest); // also calls rest->setBeam(startingBeam)
2235                         startingBeam = nullptr;
2236                         }
2237                   segment = getSegment(SegmentType::ChordRest, e.tick());
2238                   segment->add(rest);
2239                   if (fermata) {
2240                         segment->add(fermata);
2241                         fermata = nullptr;
2242                         }
2243 
2244                   if (!rest->ticks().isValid())     // hack
2245                         rest->setTicks(timesig()/timeStretch);
2246 
2247                   if (tuplet)
2248                         tuplet->add(rest);
2249                   e.incTick(rest->actualTicks());
2250                   }
2251             else if (tag == "Breath") {
2252                   Breath* breath = new Breath(score());
2253                   breath->setTrack(e.track());
2254                   breath->setPlacement(breath->track() & 1 ? Placement::BELOW : Placement::ABOVE);
2255                   breath->read(e);
2256                   segment = getSegment(SegmentType::Breath, e.tick());
2257                   segment->add(breath);
2258                   }
2259             else if (tag == "Spanner")
2260                   Spanner::readSpanner(e, this, e.track());
2261             else if (tag == "RepeatMeasure") {
2262                   RepeatMeasure* rm = new RepeatMeasure(score());
2263                   rm->setTrack(e.track());
2264                   rm->read(e);
2265                   segment = getSegment(SegmentType::ChordRest, e.tick());
2266                   segment->add(rm);
2267                   e.incTick(ticks());
2268                   }
2269             else if (tag == "Clef") {
2270                   Clef* clef = new Clef(score());
2271                   clef->setTrack(e.track());
2272                   clef->read(e);
2273                   clef->setGenerated(false);
2274 
2275                   // there may be more than one clef segment for same tick position
2276                   // the first clef may be missing and is added later in layout
2277 
2278                   bool header;
2279                   if (e.tick() != tick())
2280                         header = false;
2281                   else if (!segment)
2282                         header = true;
2283                   else {
2284                         header = true;
2285                         for (Segment* s = _segments.first(); s && s->rtick().isZero(); s = s->next()) {
2286                               if (s->isKeySigType() || s->isTimeSigType()) {
2287                                     // hack: there may be other segment types which should
2288                                     // generate a clef at current position
2289                                     header = false;
2290                                     break;
2291                                     }
2292                               }
2293                         }
2294                   segment = getSegment(header ? SegmentType::HeaderClef : SegmentType::Clef, e.tick());
2295                   segment->add(clef);
2296                   }
2297             else if (tag == "TimeSig") {
2298                   TimeSig* ts = new TimeSig(score());
2299                   ts->setTrack(e.track());
2300                   ts->read(e);
2301                   // if time sig not at beginning of measure => courtesy time sig
2302                   Fraction currTick = e.tick();
2303                   bool courtesySig = (currTick > tick());
2304                   if (courtesySig) {
2305                         // if courtesy sig., just add it without map processing
2306                         segment = getSegment(SegmentType::TimeSigAnnounce, currTick);
2307                         segment->add(ts);
2308                         }
2309                   else {
2310                         // if 'real' time sig., do full process
2311                         segment = getSegment(SegmentType::TimeSig, currTick);
2312                         segment->add(ts);
2313 
2314                         timeStretch = ts->stretch().reduced();
2315                         _timesig    = ts->sig() / timeStretch;
2316 
2317                         if (irregular) {
2318                               score()->sigmap()->add(tick().ticks(), SigEvent(_len, _timesig));
2319                               score()->sigmap()->add((tick() + ticks()).ticks(), SigEvent(_timesig));
2320                               }
2321                         else {
2322                               _len = _timesig;
2323                               score()->sigmap()->add(tick().ticks(), SigEvent(_timesig));
2324                               }
2325                         }
2326                   }
2327             else if (tag == "KeySig") {
2328                   KeySig* ks = new KeySig(score());
2329                   ks->setTrack(e.track());
2330                   ks->read(e);
2331                   Fraction curTick = e.tick();
2332                   if (!ks->isCustom() && !ks->isAtonal() && ks->key() == Key::C && curTick.isZero()) {
2333                         // ignore empty key signature
2334                         qDebug("remove keysig c at tick 0");
2335                         }
2336                   else {
2337                         // if key sig not at beginning of measure => courtesy key sig
2338                         bool courtesySig = (curTick == endTick());
2339                         segment = getSegment(courtesySig ? SegmentType::KeySigAnnounce : SegmentType::KeySig, curTick);
2340                         segment->add(ks);
2341                         if (!courtesySig)
2342                               staff->setKey(curTick, ks->keySigEvent());
2343                         }
2344                   }
2345             else if (tag == "Text") {
2346                   StaffText* t = new StaffText(score());
2347                   t->setTrack(e.track());
2348                   t->read(e);
2349                   if (t->empty()) {
2350                         qDebug("==reading empty text: deleted");
2351                         delete t;
2352                         }
2353                   else {
2354                         segment = getSegment(SegmentType::ChordRest, e.tick());
2355                         segment->add(t);
2356                         }
2357                   }
2358 
2359             //----------------------------------------------------
2360             // Annotation
2361 
2362             else if (tag == "Dynamic") {
2363                   Dynamic* dyn = new Dynamic(score());
2364                   dyn->setTrack(e.track());
2365                   dyn->read(e);
2366                   segment = getSegment(SegmentType::ChordRest, e.tick());
2367                   segment->add(dyn);
2368                   }
2369             else if (tag == "Harmony"
2370                || tag == "FretDiagram"
2371                || tag == "TremoloBar"
2372                || tag == "Symbol"
2373                || tag == "Tempo"
2374                || tag == "StaffText"
2375                || tag == "Sticking"
2376                || tag == "SystemText"
2377                || tag == "RehearsalMark"
2378                || tag == "InstrumentChange"
2379                || tag == "StaffState"
2380                || tag == "FiguredBass"
2381                ) {
2382                   Element* el = Element::name2Element(tag, score());
2383                   // hack - needed because tick tags are unreliable in 1.3 scores
2384                   // for symbols attached to anything but a measure
2385                   el->setTrack(e.track());
2386                   el->read(e);
2387                   segment = getSegment(SegmentType::ChordRest, e.tick());
2388                   segment->add(el);
2389                   }
2390             else if (tag == "Fermata") {
2391                   fermata = new Fermata(score());
2392                   fermata->setTrack(e.track());
2393                   fermata->setPlacement(fermata->track() & 1 ? Placement::BELOW : Placement::ABOVE);
2394                   fermata->read(e);
2395                   }
2396             else if (tag == "Image") {
2397                   if (MScore::noImages)
2398                         e.skipCurrentElement();
2399                   else {
2400                         Element* el = Element::name2Element(tag, score());
2401                         el->setTrack(e.track());
2402                         el->read(e);
2403                         segment = getSegment(SegmentType::ChordRest, e.tick());
2404                         segment->add(el);
2405                         }
2406                   }
2407             //----------------------------------------------------
2408             else if (tag == "Tuplet") {
2409                   Tuplet* oldTuplet = tuplet;
2410                   tuplet = new Tuplet(score());
2411                   tuplet->setTrack(e.track());
2412                   tuplet->setTick(e.tick());
2413                   tuplet->setParent(this);
2414                   tuplet->read(e);
2415                   if (oldTuplet)
2416                         oldTuplet->add(tuplet);
2417                   }
2418             else if (tag == "endTuplet") {
2419                   if (!tuplet) {
2420                         qDebug("Measure::read: encountered <endTuplet/> when no tuplet was started");
2421                         e.skipCurrentElement();
2422                         continue;
2423                         }
2424                   Tuplet* oldTuplet = tuplet;
2425                   tuplet = tuplet->tuplet();
2426                   if (oldTuplet->elements().empty()) {
2427                         // this should not happen and is a sign of input file corruption
2428                         qDebug("Measure:read: empty tuplet in measure index=%d, input file corrupted?", e.currentMeasureIndex());
2429                         if (tuplet)
2430                               tuplet->remove(oldTuplet);
2431                         delete oldTuplet;
2432                         }
2433                   e.readNext();
2434                   }
2435             else if (tag == "Beam") {
2436                   Beam* beam = new Beam(score());
2437                   beam->setTrack(e.track());
2438                   beam->read(e);
2439                   beam->setParent(0);
2440                   if (startingBeam) {
2441                         qDebug("The read beam was not used");
2442                         delete startingBeam;
2443                         }
2444                   startingBeam = beam;
2445                   }
2446             else if (tag == "Segment" && segment)
2447                   segment->read(e);
2448             else if (tag == "Ambitus") {
2449                   Ambitus* range = new Ambitus(score());
2450                   range->read(e);
2451                   segment = getSegment(SegmentType::Ambitus, e.tick());
2452                   range->setParent(segment);          // a parent segment is needed for setTrack() to work
2453                   range->setTrack(trackZeroVoice(e.track()));
2454                   segment->add(range);
2455                   }
2456             else
2457                   e.unknown();
2458             }
2459       if (startingBeam) {
2460             qDebug("The read beam was not used");
2461             delete startingBeam;
2462             }
2463       if (tuplet) {
2464             qDebug("Measure:readVoice: measure index=%d, <endTuplet/> not found", e.currentMeasureIndex());
2465             if (tuplet->elements().empty()) {
2466                   if (tuplet->tuplet())
2467                         tuplet->tuplet()->remove(tuplet);
2468                   delete tuplet;
2469                   }
2470             }
2471       if (fermata) {
2472             SegmentType st = (e.tick() == endTick() ? SegmentType::EndBarLine : SegmentType::ChordRest);
2473             segment = getSegment(st, e.tick());
2474             segment->add(fermata);
2475             fermata = nullptr;
2476             }
2477       }
2478 
2479 //---------------------------------------------------------
2480 //   Measure::readAddConnector
2481 //---------------------------------------------------------
2482 
readAddConnector(ConnectorInfoReader * info,bool pasteMode)2483 void Measure::readAddConnector(ConnectorInfoReader* info, bool pasteMode)
2484       {
2485       const ElementType type = info->type();
2486       switch(type) {
2487             case ElementType::HAIRPIN:
2488             case ElementType::PEDAL:
2489             case ElementType::OTTAVA:
2490             case ElementType::TRILL:
2491             case ElementType::TEXTLINE:
2492             case ElementType::LET_RING:
2493             case ElementType::VIBRATO:
2494             case ElementType::PALM_MUTE:
2495             case ElementType::VOLTA:
2496                   {
2497                   Spanner* sp = toSpanner(info->connector());
2498                   const Location& l = info->location();
2499                   Fraction lTick    = l.frac();
2500                   Fraction spTick   = pasteMode ? lTick : (tick() + lTick);
2501                   if (info->isStart()) {
2502                         sp->setTrack(l.track());
2503                         sp->setTick(spTick);
2504                         score()->addSpanner(sp);
2505                         }
2506                   else if (info->isEnd()) {
2507                         sp->setTrack2(l.track());
2508                         sp->setTick2(spTick);
2509                         }
2510                   }
2511                   break;
2512             default:
2513                   break;
2514             }
2515       }
2516 
2517 //---------------------------------------------------------
2518 //   visible
2519 //---------------------------------------------------------
2520 
visible(int staffIdx) const2521 bool Measure::visible(int staffIdx) const
2522       {
2523       if (staffIdx >= score()->staves().size()) {
2524             qDebug("Measure::visible: bad staffIdx: %d", staffIdx);
2525             return false;
2526             }
2527       if (system() && (system()->staves()->empty() || !system()->staff(staffIdx)->show()))
2528             return false;
2529       if (score()->staff(staffIdx)->cutaway() && isEmpty(staffIdx))
2530             return false;
2531       return score()->staff(staffIdx)->show() && _mstaves[staffIdx]->visible();
2532       }
2533 
2534 //---------------------------------------------------------
2535 //   stemless
2536 //---------------------------------------------------------
2537 
stemless(int staffIdx) const2538 bool Measure::stemless(int staffIdx) const
2539       {
2540       const Staff* staff = score()->staff(staffIdx);
2541       return staff->stemless(tick()) || _mstaves[staffIdx]->stemless() || staff->staffType(tick())->stemless();
2542       }
2543 
2544 //---------------------------------------------------------
2545 //   isFinalMeasureOfSection
2546 //    returns true if this measure is final actual measure of a section
2547 //    takes into consideration fact that subsequent measures base objects
2548 //    may have section break before encountering next actual measure
2549 //---------------------------------------------------------
2550 
isFinalMeasureOfSection() const2551 bool Measure::isFinalMeasureOfSection() const
2552       {
2553       const MeasureBase* mb = static_cast<const MeasureBase*>(this);
2554 
2555       do {
2556             if (mb->sectionBreak())
2557                   return true;
2558 
2559             mb = mb->next();
2560             } while (mb && !mb->isMeasure());   // loop until reach next actual measure or end of score
2561 
2562       return false;
2563       }
2564 
2565 //---------------------------------------------------------
2566 //   isAnacrusis
2567 //---------------------------------------------------------
2568 
isAnacrusis() const2569 bool Measure::isAnacrusis() const
2570       {
2571       TimeSigFrac timeSig = score()->sigmap()->timesig(tick().ticks()).nominal();
2572       return irregular() && ticks() < Fraction::fromTicks(timeSig.ticksPerMeasure());
2573       }
2574 
2575 //---------------------------------------------------------
2576 //   isFirstInSystem
2577 //---------------------------------------------------------
2578 
isFirstInSystem() const2579 bool Measure::isFirstInSystem() const
2580       {
2581       IF_ASSERT_FAILED(system()) {
2582             return false;
2583             }
2584       return system()->firstMeasure() == this;
2585       }
2586 
2587 //---------------------------------------------------------
2588 //   scanElements
2589 //---------------------------------------------------------
2590 
scanElements(void * data,void (* func)(void *,Element *),bool all)2591 void Measure::scanElements(void* data, void (*func)(void*, Element*), bool all)
2592       {
2593       MeasureBase::scanElements(data, func, all);
2594 
2595       int nstaves = score()->nstaves();
2596       for (int staffIdx = 0; staffIdx < nstaves; ++staffIdx) {
2597             if (!all && !score()->staff(staffIdx)->show())
2598                   continue;
2599             MStaff* ms = _mstaves[staffIdx];
2600             // show spacers and measure number even on invisible measures (TO DO: also include Staff Type Changes)
2601             if (ms->vspacerUp())
2602                   func(data, ms->vspacerUp());
2603             if (ms->vspacerDown())
2604                   func(data, ms->vspacerDown());
2605             if (ms->noText())
2606                   func(data, ms->noText());
2607             if (ms->mmRangeText())
2608                   func(data, ms->mmRangeText());
2609             // show staff lines only if measure is visible OR if it only has a courtesy clef for cutaway/ossias (short staff lines will be drawn if needed)
2610             if (visible(staffIdx) || isCutawayClef(staffIdx))
2611                   func(data, ms->lines());
2612             }
2613 
2614       for (Segment* s = first(); s; s = s->next()) {
2615             if (!s->enabled())
2616                   continue;
2617             s->scanElements(data, func, all);
2618             }
2619       }
2620 
2621 //---------------------------------------------------------
2622 //   connectTremolo
2623 ///   Connect two-notes tremolo and update duration types
2624 ///   for the involved chords.
2625 //---------------------------------------------------------
2626 
connectTremolo()2627 void Measure::connectTremolo()
2628       {
2629       const int ntracks = score()->ntracks();
2630       constexpr SegmentType st = SegmentType::ChordRest;
2631       for (Segment* s = first(st); s; s = s->next(st)) {
2632             for (int i = 0; i < ntracks; ++i) {
2633                   Element* e = s->element(i);
2634                   if (!e || !e->isChord())
2635                         continue;
2636 
2637                   Chord* c = toChord(e);
2638                   Tremolo* tremolo = c->tremolo();
2639                   if (tremolo && tremolo->twoNotes()) {
2640                         // Ensure correct duration type for chord
2641                         c->setDurationType(tremolo->durationType());
2642 
2643                         // If it is the first tremolo's chord, find the second
2644                         // chord for tremolo, if needed.
2645                         if (!tremolo->chord1())
2646                               tremolo->setChords(c, tremolo->chord2());
2647                         else if (tremolo->chord1() != c || tremolo->chord2())
2648                               continue;
2649 
2650                         for (Segment* ls = s->next(st); ls; ls = ls->next(st)) {
2651                               if (Element* element = ls->element(i)) {
2652                                     if (!element->isChord()) {
2653                                           qDebug("cannot connect tremolo");
2654                                           continue;
2655                                           }
2656                                     Chord* nc = toChord(element);
2657                                     tremolo->setChords(c, nc);
2658                                     nc->setTremolo(tremolo);
2659                                     break;
2660                                     }
2661                               }
2662                         }
2663                   }
2664             }
2665       }
2666 
2667 //---------------------------------------------------------
2668 //   createVoice
2669 //    Create a voice on demand by filling the measure
2670 //    with a whole measure rest.
2671 //    Check if there are any chord/rests in track; if
2672 //    not create a whole measure rest
2673 //---------------------------------------------------------
2674 
createVoice(int track)2675 void Measure::createVoice(int track)
2676       {
2677       for (Segment* s = first(); s; s = s->next()) {
2678             if (s->segmentType() != SegmentType::ChordRest)
2679                   continue;
2680             if (s->element(track) == 0)
2681                   score()->setRest(s->tick(), track, ticks(), true, 0);
2682             break;
2683             }
2684       }
2685 
2686 //---------------------------------------------------------
2687 //   sortStaves
2688 //---------------------------------------------------------
2689 
sortStaves(QList<int> & dst)2690 void Measure::sortStaves(QList<int>& dst)
2691       {
2692       std::vector<MStaff*> ms;
2693       for (int idx : dst)
2694             ms.push_back(_mstaves[idx]);
2695       _mstaves = ms;
2696 
2697       for (unsigned staffIdx = 0; staffIdx < _mstaves.size(); ++staffIdx)
2698             _mstaves[staffIdx]->lines()->setTrack(staffIdx * VOICES);
2699       for (Segment& s : _segments)
2700             s.sortStaves(dst);
2701 
2702       for (Element* e : el()) {
2703             if (e->track() == -1 || e->systemFlag())
2704                   continue;
2705             int voice    = e->voice();
2706             int staffIdx = e->staffIdx();
2707             int idx = dst.indexOf(staffIdx);
2708             e->setTrack(idx * VOICES + voice);
2709             }
2710       }
2711 
2712 //---------------------------------------------------------
2713 //   exchangeVoice
2714 //---------------------------------------------------------
2715 
exchangeVoice(int strack,int dtrack,int staffIdx)2716 void Measure::exchangeVoice(int strack, int dtrack, int staffIdx)
2717       {
2718       for (Segment* s = first(SegmentType::ChordRest); s; s = s->next(SegmentType::ChordRest)) {
2719             s->swapElements(strack, dtrack);
2720             }
2721 
2722       auto spanners = score()->spannerMap().findOverlapping(tick().ticks(), endTick().ticks()-1);
2723       Fraction start = tick();
2724       Fraction end = start + ticks();
2725       for (auto i = spanners.begin(); i < spanners.end(); i++) {
2726             Spanner* sp = i->value;
2727             Fraction spStart = sp->tick();
2728             Fraction spEnd = spStart + sp->ticks();
2729             qDebug("Start %d End %d Diff %d \n Measure Start %d End %d", spStart.ticks(), spEnd.ticks(), (spEnd-spStart).ticks(), start.ticks(), end.ticks());
2730             if (sp->isSlur() && (spStart >= start || spEnd < end)) {
2731                 if (sp->track() == strack && spStart >= start){
2732                         sp->setTrack(dtrack);
2733                         }
2734                 else if (sp->track() == dtrack && spStart >= start){
2735                         sp->setTrack(strack);
2736                         }
2737                 if (sp->track2() == strack && spEnd < end){
2738                         sp->setTrack2(dtrack);
2739                         }
2740                 else if (sp->track2() == dtrack && spEnd < end){
2741                         sp->setTrack2(strack);
2742                         }
2743                   }
2744             }
2745       checkMultiVoices(staffIdx);   // probably true, but check for invisible notes & rests
2746       }
2747 
2748 //---------------------------------------------------------
2749 //   checkMultiVoices
2750 ///   Check for more than on voice in this measure and staff and
2751 ///   set MStaff->hasVoices
2752 //---------------------------------------------------------
2753 
checkMultiVoices(int staffIdx)2754 void Measure::checkMultiVoices(int staffIdx)
2755       {
2756       if (hasVoices(staffIdx, tick(), ticks()))
2757             _mstaves[staffIdx]->setHasVoices(true);
2758       else
2759             _mstaves[staffIdx]->setHasVoices(false);
2760       }
2761 
2762 //---------------------------------------------------------
2763 //   hasVoices
2764 //---------------------------------------------------------
2765 
hasVoices(int staffIdx,Fraction stick,Fraction len) const2766 bool Measure::hasVoices(int staffIdx, Fraction stick, Fraction len) const
2767       {
2768       Staff* st = score()->staff(staffIdx);
2769       if (st->isTabStaff(stick)) {
2770             // TODO: tab staves use different rules for stem directin etc
2771             // see for example https://musescore.org/en/node/308371
2772             // we should consider coming up with a more comprehensive solution
2773             // but for now, we are forcing measures on tab staves to be consider as a whole -
2774             // either they have voices or not
2775             // (rather than checking tick ranges)
2776             stick = tick();
2777             len = stretchedLen(st);
2778             }
2779       int strack = staffIdx * VOICES + 1;
2780       int etrack = staffIdx * VOICES + VOICES;
2781       Fraction etick = stick + len;
2782 
2783       for (Segment* s = first(SegmentType::ChordRest); s; s = s->next(SegmentType::ChordRest)) {
2784             if (s->tick() >= etick)
2785                   break;
2786             for (int track = strack; track < etrack; ++track) {
2787                   ChordRest* cr = toChordRest(s->element(track));
2788                   if (cr) {
2789                         if (cr->tick() + cr->actualTicks() <= stick)
2790                               continue;
2791                         bool v = false;
2792                         if (cr->isChord()) {
2793                               // consider chord visible if any note is visible
2794                               Chord* c = toChord(cr);
2795                               for (Note* n : c->notes()) {
2796                                     if (n->visible()) {
2797                                           v = true;
2798                                           break;
2799                                           }
2800                                     }
2801                               }
2802                         else if (cr->isRest())
2803                               v = cr->visible() && !toRest(cr)->isGap();
2804                         if (v)
2805                               return true;
2806                         }
2807                   }
2808             }
2809       return false;
2810       }
2811 
2812 //---------------------------------------------------------
2813 //   hasVoice
2814 //---------------------------------------------------------
2815 
hasVoice(int track) const2816 bool Measure::hasVoice(int track) const
2817       {
2818       if (track >= score()->ntracks())
2819             return false;
2820       for (Segment* s = first(); s; s = s->next()) {
2821             if (s->segmentType() != SegmentType::ChordRest)
2822                   continue;
2823             if (s->element(track))
2824                   return true;
2825             }
2826       return false;
2827       }
2828 
2829 //-------------------------------------------------------------------
2830 //   isEmpty
2831 ///   Check if the measure is filled by a full-measure rest, or is
2832 ///   full of rests on this staff, that may have fermatas on them.
2833 ///   If staff is -1, then check for all staves.
2834 //-------------------------------------------------------------------
2835 
isEmpty(int staffIdx) const2836 bool Measure::isEmpty(int staffIdx) const
2837       {
2838       int strack;
2839       int etrack;
2840       bool hasStaves = score()->staff(staffIdx)->part()->staves()->size() > 1;
2841       if (staffIdx < 0) {
2842             strack = 0;
2843             etrack = score()->nstaves() * VOICES;
2844             }
2845       else {
2846             strack = staffIdx * VOICES;
2847             etrack = strack + VOICES;
2848             }
2849       for (Segment* s = first(SegmentType::ChordRest); s; s = s->next(SegmentType::ChordRest)) {
2850             for (int track = strack; track < etrack; ++track) {
2851                   Element* e = s->element(track);
2852                   if (e && !e->isRest())
2853                         return false;
2854                   // Check for cross-staff chords
2855                   if (hasStaves) {
2856                         if (strack >= VOICES) {
2857                               e = s->element(track - VOICES);
2858                               if (e && !e->isRest() && e->vStaffIdx() == staffIdx)
2859                                     return false;
2860                               }
2861                         if (etrack < score()->nstaves() * VOICES) {
2862                               e = s->element(track + VOICES);
2863                               if (e && !e->isRest() && e->vStaffIdx() == staffIdx)
2864                                     return false;
2865                               }
2866                         }
2867                   }
2868             for (Element* a : s->annotations()) {
2869                   if (!a || a->systemFlag() || !a->visible() || a->isFermata())
2870                         continue;
2871                   int atrack = a->track();
2872                   if (atrack >= strack && atrack < etrack)
2873                         return false;
2874                   }
2875             }
2876       return true;
2877       }
2878 
2879 //---------------------------------------------------------
2880 //   isCutawayClef
2881 ///    Check for empty measure with only
2882 ///    a Courtesy Clef before End Bar Line
2883 //---------------------------------------------------------
2884 
isCutawayClef(int staffIdx) const2885 bool Measure::isCutawayClef(int staffIdx) const
2886       {
2887       if (!score()->staff(staffIdx) || !_mstaves[staffIdx])
2888             return false;
2889       bool empty = (score()->staff(staffIdx)->cutaway() && isEmpty(staffIdx)) || !_mstaves[staffIdx]->visible();
2890       if (!empty)
2891             return false;
2892       int strack;
2893       int etrack;
2894       if (staffIdx < 0) {
2895             strack = 0;
2896             etrack = score()->nstaves() * VOICES;
2897             }
2898       else {
2899             strack = staffIdx * VOICES;
2900             etrack = strack + VOICES;
2901             }
2902       // find segment before EndBarLine
2903       Segment* s = nullptr;
2904       for (Segment* ls = last(); ls; ls = ls->prev()) {
2905             if (ls->segmentType() ==  SegmentType::EndBarLine) {
2906                   s = ls->prev();
2907                   break;
2908                   }
2909             }
2910       if (!s)
2911             return false;
2912       for (int track = strack; track < etrack; ++track) {
2913             Element* e = s->element(track);
2914             if (!e || !e->isClef())
2915                   continue;
2916             if ((nextMeasure() && (nextMeasure()->system() == system())) || toClef(e)->showCourtesy())
2917                   return true;
2918             }
2919       return false;
2920       }
2921 
2922 //---------------------------------------------------------
2923 //   isFullMeasureRest
2924 //    Check for an empty measure, filled with full measure
2925 //    rests.
2926 //---------------------------------------------------------
2927 
isFullMeasureRest() const2928 bool Measure::isFullMeasureRest() const
2929       {
2930       int strack = 0;
2931       int etrack = score()->nstaves() * VOICES;
2932 
2933       Segment* s = first(SegmentType::ChordRest);
2934       for (int track = strack; track < etrack; ++track) {
2935             Element* e = s->element(track);
2936             if (e) {
2937                   if (!e->isRest())
2938                         return false;
2939                   Rest* rest = toRest(e);
2940                   if (rest->durationType().type() != TDuration::DurationType::V_MEASURE)
2941                         return false;
2942                   }
2943             }
2944       return true;
2945       }
2946 
2947 //---------------------------------------------------------
2948 //   isRepeatMeasure
2949 //---------------------------------------------------------
2950 
isRepeatMeasure(const Staff * staff) const2951 bool Measure::isRepeatMeasure(const Staff* staff) const
2952       {
2953       int staffIdx = staff->idx();
2954       int strack   = staffIdx * VOICES;
2955       int etrack   = (staffIdx + 1) * VOICES;
2956       Segment* s   = first(SegmentType::ChordRest);
2957 
2958       if (s == 0)
2959             return false;
2960 
2961       for (int track = strack; track < etrack; ++track) {
2962             Element* e = s->element(track);
2963             if (e && e->isRepeatMeasure())
2964                   return true;
2965             }
2966       return false;
2967       }
2968 
2969 //---------------------------------------------------------
2970 //   isEmpty
2971 //---------------------------------------------------------
2972 
empty() const2973 bool Measure::empty() const
2974       {
2975       if (irregular())
2976             return false;
2977       int n = 0;
2978       int tracks = int(_mstaves.size()) * VOICES;
2979       static const SegmentType st = SegmentType::ChordRest ;
2980       for (const Segment* s = first(st); s; s = s->next(st)) {
2981             bool restFound = false;
2982             for (int track = 0; track < tracks; ++track) {
2983                   if ((track % VOICES) == 0 && !score()->staff(track/VOICES)->show()) {
2984                         track += VOICES-1;
2985                         continue;
2986                         }
2987                   if (s->element(track))  {
2988                         if (!s->element(track)->isRest())
2989                               return false;
2990                         restFound = true;
2991                         }
2992                   }
2993             if (restFound)
2994                   ++n;
2995             // measure is not empty if there is more than one rest
2996             if (n > 1)
2997                   return false;
2998             }
2999       return true;
3000       }
3001 
3002 //---------------------------------------------------------
3003 //   isOnlyRests
3004 //---------------------------------------------------------
3005 
isOnlyRests(int track) const3006 bool Measure::isOnlyRests(int track) const
3007       {
3008       static const SegmentType st = SegmentType::ChordRest;
3009       for (const Segment* s = first(st); s; s = s->next(st)) {
3010             if (s->segmentType() != st || !s->element(track))
3011                   continue;
3012             if (!s->element(track)->isRest())
3013                   return false;
3014             }
3015       return true;
3016       }
3017 
3018 //---------------------------------------------------------
3019 //   isOnlyDeletedRests
3020 //---------------------------------------------------------
3021 
isOnlyDeletedRests(int track) const3022 bool Measure::isOnlyDeletedRests(int track) const
3023       {
3024       static const SegmentType st { SegmentType::ChordRest };
3025       for (const Segment* s = first(st); s; s = s->next(st)) {
3026             if (s->segmentType() != st || !s->element(track))
3027                   continue;
3028             if (s->element(track)->isRest() ? !toRest(s->element(track))->isGap() : !s->element(track)->isRest())
3029                   return false;
3030             }
3031       return true;
3032       }
3033 
3034 //---------------------------------------------------------
3035 //   stretchedLen
3036 //---------------------------------------------------------
3037 
stretchedLen(Staff * staff) const3038 Fraction Measure::stretchedLen(Staff* staff) const
3039       {
3040       return ticks() * staff->timeStretch(tick());
3041       }
3042 
3043 //---------------------------------------------------------
3044 //   cloneMeasure
3045 //---------------------------------------------------------
3046 
cloneMeasure(Score * sc,const Fraction & tick,TieMap * tieMap)3047 Measure* Measure::cloneMeasure(Score* sc, const Fraction& tick, TieMap* tieMap)
3048       {
3049       Measure* m      = new Measure(sc);
3050       m->_timesig     = _timesig;
3051       m->_len         = _len;
3052       m->_repeatCount = _repeatCount;
3053 
3054       Q_ASSERT(sc->staves().size() >= int(_mstaves.size())); // destination score we're cloning into must have at least as many staves as measure being cloned
3055 
3056       m->setNo(no());
3057       m->setNoOffset(noOffset());
3058       m->setIrregular(irregular());
3059       m->_userStretch           = _userStretch;
3060       m->_breakMultiMeasureRest = _breakMultiMeasureRest;
3061       m->_playbackCount         = _playbackCount;
3062 
3063       m->setTick(tick);
3064       m->setLineBreak(lineBreak());
3065       m->setPageBreak(pageBreak());
3066       m->setSectionBreak(sectionBreak() ? new LayoutBreak(*sectionBreakElement()) : 0);
3067 
3068       m->setHeader(header()); m->setTrailer(trailer());
3069 
3070       int tracks = sc->nstaves() * VOICES;
3071       TupletMap tupletMap;
3072 
3073       for (Segment* oseg = first(); oseg; oseg = oseg->next()) {
3074             Segment* s = new Segment(m, oseg->segmentType(), oseg->rtick());
3075             s->setEnabled(oseg->enabled()); s->setVisible(oseg->visible());
3076             s->setHeader(oseg->header()); s->setTrailer(oseg->trailer());
3077 
3078             m->_segments.push_back(s);
3079             for (int track = 0; track < tracks; ++track) {
3080                   Element* oe = oseg->element(track);
3081                   for (Element* e : oseg->annotations()) {
3082                         if (e->generated() || e->track() != track)
3083                               continue;
3084                         Element* ne = e->clone();
3085                         ne->setTrack(track);
3086                         ne->setOffset(e->offset());
3087                         ne->setScore(sc);
3088                         s->add(ne);
3089                         }
3090                   if (!oe)
3091                         continue;
3092                   Element* ne = oe->clone();
3093                   if (oe->isChordRest()) {
3094                         ChordRest* ocr = toChordRest(oe);
3095                         ChordRest* ncr = toChordRest(ne);
3096                         Tuplet* ot     = ocr->tuplet();
3097                         if (ot) {
3098                               Tuplet* nt = tupletMap.findNew(ot);
3099                               if (nt == 0) {
3100                                     nt = new Tuplet(*ot);
3101                                     nt->clear();
3102                                     nt->setTrack(track);
3103                                     nt->setScore(sc);
3104                                     nt->setParent(m);
3105                                     nt->setTick(m->tick() + ot->rtick());
3106                                     tupletMap.add(ot, nt);
3107                                     }
3108                               ncr->setTuplet(nt);
3109                               nt->add(ncr);
3110                               }
3111                         if (oe->isChord()) {
3112                               Chord* och = toChord(ocr);
3113                               Chord* nch = toChord(ncr);
3114                               size_t n = och->notes().size();
3115                               for (size_t i = 0; i < n; ++i) {
3116                                     Note* on = och->notes().at(i);
3117                                     Note* nn = nch->notes().at(i);
3118                                     if (on->tieFor()) {
3119                                           Tie* tie = on->tieFor()->clone();
3120                                           tie->setScore(sc);
3121                                           nn->setTieFor(tie);
3122                                           tie->setStartNote(nn);
3123                                           tieMap->add(on->tieFor(), tie);
3124                                           }
3125                                     if (on->tieBack()) {
3126                                           Tie* tie = tieMap->findNew(on->tieBack());
3127                                           if (tie) {
3128                                                 nn->setTieBack(tie);
3129                                                 tie->setEndNote(nn);
3130                                                 }
3131                                           else {
3132                                                 qDebug("cloneMeasure: cannot find tie, track %d", track);
3133                                                 }
3134                                           }
3135                                     }
3136                               }
3137                         }
3138                   ne->setOffset(oe->offset());
3139                   ne->setScore(sc);
3140                   s->add(ne);
3141                   }
3142             }
3143       for (Element* e : el()) {
3144             Element* ne = e->clone();
3145             ne->setScore(sc);
3146             ne->setOffset(e->offset());
3147             m->add(ne);
3148             }
3149       return m;
3150       }
3151 
3152 //---------------------------------------------------------
3153 //   snap
3154 //---------------------------------------------------------
3155 
snap(const Fraction & tick,const QPointF p) const3156 Fraction Measure::snap(const Fraction& tick, const QPointF p) const
3157       {
3158       Segment* s = first();
3159       for (; s->next(); s = s->next()) {
3160             qreal x  = s->x();
3161             qreal dx = s->next()->x() - x;
3162             if (s->tick() == tick)
3163                   x += dx / 3.0 * 2.0;
3164             else  if (s->next()->tick() == tick)
3165                   x += dx / 3.0;
3166             else
3167                   x += dx * .5;
3168             if (p.x() < x)
3169                   break;
3170             }
3171       return s->tick();
3172       }
3173 
3174 //---------------------------------------------------------
3175 //   snapNote
3176 //---------------------------------------------------------
3177 
snapNote(const Fraction &,const QPointF p,int staff) const3178 Fraction Measure::snapNote(const Fraction& /*tick*/, const QPointF p, int staff) const
3179       {
3180       Segment* s = first();
3181       for (;;) {
3182             Segment* ns = s->next();
3183             while (ns && ns->element(staff) == 0)
3184                   ns = ns->next();
3185             if (ns == 0)
3186                   break;
3187             qreal x  = s->x();
3188             qreal nx = x + (ns->x() - x) * .5;
3189             if (p.x() < nx)
3190                   break;
3191             s = ns;
3192             }
3193       return s->tick();
3194       }
3195 
3196 //---------------------------------------------------------
3197 //   searchSegment
3198 ///   Finds a segment which x position is most close to the
3199 ///   given \p x.
3200 ///   \param x The x coordinate in measure coordinates.
3201 ///   \param st Type of segments to search.
3202 ///   \param strack start of track range (strack included)
3203 ///   in which the found segment should contain elements.
3204 ///   \param etrack end of track range (etrack excluded)
3205 ///   in which the found segment should contain elements.
3206 ///   \param preferredSegment If not nullptr, will give
3207 ///   more space to the given segment when searching it by
3208 ///   coordinate.
3209 ///   \returns The segment that was found.
3210 //---------------------------------------------------------
3211 
searchSegment(qreal x,SegmentType st,int strack,int etrack,const Segment * preferredSegment,qreal spacingFactor) const3212 Segment* Measure::searchSegment(qreal x, SegmentType st, int strack, int etrack, const Segment* preferredSegment, qreal spacingFactor) const
3213       {
3214       const int lastTrack = etrack - 1;
3215       for (Segment* segment = first(st); segment; segment = segment->next(st)) {
3216             if (!segment->hasElements(strack, lastTrack))
3217                   continue;
3218             Segment* ns = segment->next(st);
3219             for (; ns; ns = ns->next(st)) {
3220                   if (ns->hasElements(strack, lastTrack))
3221                         break;
3222                   }
3223             if (!ns)
3224                   return segment;
3225             if (preferredSegment == segment) {
3226                   if (x < (segment->x() + (ns->x() - segment->x())))
3227                         return segment;
3228                   }
3229             else if (preferredSegment == ns) {
3230                   if (x <= segment->x())
3231                         return segment;
3232                   }
3233             else {
3234                   if (x < (segment->x() + (ns->x() - segment->x()) * spacingFactor))
3235                         return segment;
3236                   }
3237             }
3238       return nullptr;
3239       }
3240 
3241 //---------------------------------------------------------
3242 //   getProperty
3243 //---------------------------------------------------------
3244 
getProperty(Pid propertyId) const3245 QVariant Measure::getProperty(Pid propertyId) const
3246       {
3247       switch(propertyId) {
3248             case Pid::TIMESIG_NOMINAL:
3249                   return QVariant::fromValue(_timesig);
3250             case Pid::TIMESIG_ACTUAL:
3251                   return QVariant::fromValue(_len);
3252             case Pid::MEASURE_NUMBER_MODE:
3253                   return int(measureNumberMode());
3254             case Pid::BREAK_MMR:
3255                   return breakMultiMeasureRest();
3256             case Pid::REPEAT_COUNT:
3257                   return repeatCount();
3258             case Pid::USER_STRETCH:
3259                   return userStretch();
3260             default:
3261                   return MeasureBase::getProperty(propertyId);
3262             }
3263       }
3264 
3265 //---------------------------------------------------------
3266 //   setProperty
3267 //---------------------------------------------------------
3268 
setProperty(Pid propertyId,const QVariant & value)3269 bool Measure::setProperty(Pid propertyId, const QVariant& value)
3270       {
3271       switch (propertyId) {
3272             case Pid::TIMESIG_NOMINAL:
3273                   _timesig = value.value<Fraction>();
3274                   break;
3275             case Pid::TIMESIG_ACTUAL:
3276                   _len = value.value<Fraction>();
3277                   break;
3278             case Pid::MEASURE_NUMBER_MODE:
3279                   setMeasureNumberMode(MeasureNumberMode(value.toInt()));
3280                   break;
3281             case Pid::BREAK_MMR:
3282                   setBreakMultiMeasureRest(value.toBool());
3283                   break;
3284             case Pid::REPEAT_COUNT:
3285                   setRepeatCount(value.toInt());
3286                   break;
3287             case Pid::USER_STRETCH:
3288                   setUserStretch(value.toDouble());
3289                   break;
3290             default:
3291                   return MeasureBase::setProperty(propertyId, value);
3292             }
3293       triggerLayout();
3294       return true;
3295       }
3296 
3297 //---------------------------------------------------------
3298 //   propertyDefault
3299 //---------------------------------------------------------
3300 
propertyDefault(Pid propertyId) const3301 QVariant Measure::propertyDefault(Pid propertyId) const
3302       {
3303       switch(propertyId) {
3304             case Pid::TIMESIG_NOMINAL:
3305             case Pid::TIMESIG_ACTUAL:
3306                   return QVariant();
3307             case Pid::MEASURE_NUMBER_MODE:
3308                   return int(MeasureNumberMode::AUTO);
3309             case Pid::BREAK_MMR:
3310                   return false;
3311             case Pid::REPEAT_COUNT:
3312                   return 2;
3313             case Pid::USER_STRETCH:
3314                   return 1.0;
3315             case Pid::NO_OFFSET:
3316                   return 0;
3317             case Pid::IRREGULAR:
3318                   return false;
3319             default:
3320                   break;
3321             }
3322       return MeasureBase::propertyDefault(propertyId);
3323       }
3324 
3325 //-------------------------------------------------------------------
3326 //   mmRestFirst
3327 //    this is a multi measure rest
3328 //    returns first measure of replaced sequence of empty measures
3329 //-------------------------------------------------------------------
3330 
mmRestFirst() const3331 Measure* Measure::mmRestFirst() const
3332       {
3333       Q_ASSERT(isMMRest());
3334       if (prev())
3335             return toMeasure(prev()->next());
3336       return score()->firstMeasure();
3337       }
3338 
3339 //-------------------------------------------------------------------
3340 //   mmRestLast
3341 //    this is a multi measure rest
3342 //    returns last measure of replaced sequence of empty measures
3343 //-------------------------------------------------------------------
3344 
mmRestLast() const3345 Measure* Measure::mmRestLast() const
3346       {
3347       Q_ASSERT(isMMRest());
3348       if (next())
3349             return toMeasure(next()->prev());
3350       return score()->lastMeasure();
3351       }
3352 
3353 //---------------------------------------------------------
3354 //   mmRest1
3355 //    return the multi measure rest this measure is covered
3356 //    by
3357 //---------------------------------------------------------
3358 
mmRest1() const3359 const Measure* Measure::mmRest1() const
3360       {
3361       if (_mmRest)
3362             return _mmRest;
3363       if (_mmRestCount != -1)
3364             // return const_cast<Measure*>(this);
3365             return this;
3366       const Measure* m = this;
3367       while (m && !m->_mmRest)
3368             m = m->prevMeasure();
3369       if (m)
3370             return const_cast<Measure*>(m->_mmRest);
3371       return 0;
3372       }
3373 
3374 //-------------------------------------------------------------------
3375 //   userStretch
3376 //-------------------------------------------------------------------
3377 
userStretch() const3378 qreal Measure::userStretch() const
3379       {
3380       return (score()->layoutMode() == LayoutMode::FLOAT ? 1.0 : _userStretch);
3381       }
3382 
3383 //---------------------------------------------------------
3384 //   nextElementStaff
3385 //---------------------------------------------------------
3386 
nextElementStaff(int staff)3387 Element* Measure::nextElementStaff(int staff)
3388       {
3389       Element* e = score()->selection().element();
3390       if (!e && !score()->selection().elements().isEmpty())
3391             e = score()->selection().elements().first();
3392 
3393       // handle measure elements
3394       if (e->parent() == this) {
3395             auto i = std::find(el().begin(), el().end(), e);
3396             if (i != el().end()) {
3397                   if (++i != el().end()) {
3398                         Element* resElement = *i;
3399                         if (resElement)
3400                               return resElement;
3401                         }
3402                   }
3403             }
3404 
3405       for (; e && e->type() != ElementType::SEGMENT; e = e->parent()) {
3406             ;
3407       }
3408       Segment* seg = toSegment(e);
3409       Segment* nextSegment = seg ? seg->next() : first();
3410       Element* next = seg->firstElementOfSegment(nextSegment, staff);
3411       if (next)
3412             return next;
3413 
3414       return score()->lastElement();
3415       }
3416 
3417 //---------------------------------------------------------
3418 //   prevElementStaff
3419 //---------------------------------------------------------
3420 
prevElementStaff(int staff)3421 Element* Measure::prevElementStaff(int staff)
3422       {
3423       Element* e = score()->selection().element();
3424       if (!e && !score()->selection().elements().isEmpty())
3425             e = score()->selection().elements().first();
3426 
3427       // handle measure elements
3428       if (e->parent() == this) {
3429             auto i = std::find(el().rbegin(), el().rend(), e);
3430             if (i != el().rend()) {
3431                   if (++i != el().rend()) {
3432                         Element* resElement = *i;
3433                         if (resElement)
3434                               return resElement;
3435                         }
3436                   }
3437             }
3438 
3439       Measure* prevM = prevMeasureMM();
3440       if (prevM) {
3441             Segment* seg = prevM->last();
3442             if (seg)
3443                   return seg->lastElement(staff);
3444             }
3445       return score()->firstElement();
3446       }
3447 
3448 //---------------------------------------------------------
3449 //   accessibleInfo
3450 //---------------------------------------------------------
3451 
accessibleInfo() const3452 QString Measure::accessibleInfo() const
3453       {
3454       return QString("%1: %2").arg(Element::accessibleInfo(), QString::number(no() + 1));
3455       }
3456 
3457 //-----------------------------------------------------------------------------
3458 //    stretchMeasure
3459 //    resize width of measure to targetWidth
3460 //-----------------------------------------------------------------------------
3461 
stretchMeasure(qreal targetWidth)3462 void Measure::stretchMeasure(qreal targetWidth)
3463       {
3464       bbox().setWidth(targetWidth);
3465 
3466       Fraction minTick = computeTicks();
3467 
3468       //---------------------------------------------------
3469       //    compute stretch
3470       //---------------------------------------------------
3471 
3472       std::multimap<qreal, Segment*> springs;
3473 
3474       Segment* seg = first();
3475       while (seg && !seg->enabled())
3476             seg = seg->next();
3477       qreal minimumWidth = seg ? seg->x() : 0.0;
3478       for (Segment& s : _segments) {
3479             if (!s.enabled() || !s.visible())
3480                   continue;
3481             Fraction t = s.ticks();
3482             if (t.isNotZero()) {
3483                   qreal str = 1.0 + 0.865617 * log(qreal(t.ticks()) / qreal(minTick.ticks())); // .6 * log(t / minTick.ticks()) / log(2);
3484                   qreal d   = s.width() / str;
3485                   s.setStretch(str);
3486                   springs.insert(std::pair<qreal, Segment*>(d, &s));
3487                   }
3488             minimumWidth += s.width();
3489             }
3490 
3491       //---------------------------------------------------
3492       //    compute 1/Force for a given Extend
3493       //---------------------------------------------------
3494 
3495       if (targetWidth > minimumWidth) {
3496             qreal force = 0;
3497             qreal c     = 0.0;
3498             for (auto i = springs.begin(); i != springs.end();) {
3499                   c            += i->second->stretch();
3500                   minimumWidth -= i->second->width();
3501                   qreal f       = (targetWidth - minimumWidth) / c;
3502                   ++i;
3503                   if (i == springs.end() || f <= i->first) {
3504                         force = f;
3505                         break;
3506                         }
3507                   }
3508 
3509             //---------------------------------------------------
3510             //    distribute stretch to segments
3511             //---------------------------------------------------
3512 
3513             for (auto& i : springs) {
3514                   qreal width = force * i.second->stretch();
3515                   if (width > i.second->width())
3516                         i.second->setWidth(width);
3517                   }
3518 
3519             //---------------------------------------------------
3520             //    move segments to final position
3521             //---------------------------------------------------
3522 
3523             Segment* s = first();
3524             while (s && !s->enabled())
3525                   s = s->next();
3526             qreal x = s ? s->pos().x() : 0.0;
3527             while (s) {
3528                   s->rxpos() = x;
3529                   x += s->width();
3530                   s = s->nextEnabled();
3531                   }
3532             }
3533 
3534       //---------------------------------------------------
3535       //    layout individual elements
3536       //---------------------------------------------------
3537 
3538       for (Segment& s : _segments) {
3539             if (!s.enabled())
3540                   continue;
3541             for (Element* e : s.elist()) {
3542                   if (!e)
3543                         continue;
3544                   ElementType t = e->type();
3545                   int staffIdx    = e->staffIdx();
3546                   if (t == ElementType::REPEAT_MEASURE || (t == ElementType::REST && (isMMRest() || toRest(e)->isFullMeasureRest()))) {
3547                         //
3548                         // element has to be centered in free space
3549                         //    x1 - left measure position of free space
3550                         //    x2 - right measure position of free space
3551 
3552                         Segment* s1;
3553                         for (s1 = s.prevActive(); s1 && s1->allElementsInvisible(); s1 = s1->prevActive())
3554                               ;
3555                         Segment* s2;
3556                         for (s2 = s.nextActive(); s2; s2 = s2->nextActive()) {
3557                               if (!s2->isChordRestType() && s2->element(staffIdx * VOICES))
3558                                     break;
3559                               }
3560                         qreal x1 = s1 ? s1->x() + s1->minRight() : 0;
3561                         qreal x2 = s2 ? s2->x() - s2->minLeft() : targetWidth;
3562 
3563                         if (isMMRest()) {
3564                               Rest* rest = toRest(e);
3565                               //
3566                               // center multi measure rest
3567                               //
3568                               qreal d = score()->styleP(Sid::multiMeasureRestMargin);
3569                               qreal w = x2 - x1 - 2 * d;
3570 
3571                               rest->layoutMMRest(w);
3572                               e->setPos(x1 - s.x() + d, e->staff()->height() * .5);   // center vertically in measure
3573                               s.createShape(staffIdx);
3574                               }
3575                         else { // if (rest->isFullMeasureRest()) {
3576                               //
3577                               // center full measure rest
3578                               //
3579                               e->rxpos() = (x2 - x1 - e->width()) * .5 + x1 - s.x() - e->bbox().x();
3580                               s.createShape(staffIdx);  // DEBUG
3581                               }
3582                         }
3583                   else if (t == ElementType::REST)
3584                         e->rxpos() = 0;
3585                   else if (t == ElementType::CHORD) {
3586                         Chord* c = toChord(e);
3587                         c->layout2();
3588                         if (c->tremolo()) {
3589                               Tremolo* tr = c->tremolo();
3590                               Chord* c1 = tr->chord1();
3591                               Chord* c2 = tr->chord2();
3592                               if (!tr->twoNotes() || (c1 && !c1->staffMove() && c2 && !c2->staffMove()))
3593                                     tr->layout();
3594                               }
3595                         }
3596                   else if (t == ElementType::BAR_LINE) {
3597                         e->rypos() = 0.0;
3598                         // for end barlines, x position was set in createEndBarLines
3599                         if (s.segmentType() != SegmentType::EndBarLine)
3600                               e->rxpos() = 0.0;
3601                         }
3602                   }
3603             }
3604       }
3605 
3606 //---------------------------------------------------
3607 //    computeTicks
3608 //    set ticks for all segments
3609 //       return minTick
3610 //---------------------------------------------------
3611 
computeTicks()3612 Fraction Measure::computeTicks()
3613       {
3614       Fraction minTick = ticks();
3615       if (minTick <= Fraction(0,1)) {
3616             qDebug("=====minTick %d measure %p", minTick.ticks(), this);
3617             }
3618       Q_ASSERT(minTick > Fraction(0,1));
3619 
3620       Segment* ns = first();
3621       while (ns && !ns->enabled())
3622             ns = ns->next();
3623       while (ns) {
3624             Segment* s = ns;
3625             ns         = s->nextActive();
3626             Fraction nticks = (ns ? ns->rtick() : ticks()) - s->rtick();
3627             if (nticks.isNotZero()) {
3628                   if (nticks < minTick)
3629                         minTick = nticks;
3630                   }
3631             s->setTicks(nticks);
3632             }
3633       return minTick;
3634       }
3635 
3636 //---------------------------------------------------------
3637 //   endBarLine
3638 //      return the first one
3639 //---------------------------------------------------------
3640 
endBarLine() const3641 const BarLine* Measure::endBarLine() const
3642       {
3643       // search barline segment:
3644       Segment* s = last();
3645       while (s && !s->isEndBarLineType())
3646             s = s->prev();
3647       // search first element
3648       if (s) {
3649             for (const Element* e : s->elist()) {
3650                   if (e)
3651                         return toBarLine(e);
3652                   }
3653             }
3654       return 0;
3655       }
3656 
3657 //---------------------------------------------------------
3658 //   endBarLineType
3659 //    Assume all barlines have same type if there is more
3660 //    than one.
3661 //---------------------------------------------------------
3662 
endBarLineType() const3663 BarLineType Measure::endBarLineType() const
3664       {
3665       const BarLine* bl = endBarLine();
3666       return bl ? bl->barLineType() : BarLineType::NORMAL;
3667       }
3668 
3669 //---------------------------------------------------------
3670 //   endBarLineType
3671 //    Assume all barlines have same visibility if there is more
3672 //    than one.
3673 //---------------------------------------------------------
3674 
endBarLineVisible() const3675 bool Measure::endBarLineVisible() const
3676       {
3677       const BarLine* bl = endBarLine();
3678       return bl ? bl->visible() : true;
3679       }
3680 
3681 //---------------------------------------------------------
3682 //   triggerLayout
3683 //---------------------------------------------------------
3684 
triggerLayout() const3685 void Measure::triggerLayout() const
3686       {
3687       if (prev() || next()) // avoid triggering layout before getting added to a score
3688             score()->setLayout(tick(), endTick(), 0, score()->nstaves() - 1, this);
3689       }
3690 
3691 //---------------------------------------------------------
3692 //   setEndBarLineType
3693 //     Create a *generated* barline with the given type and
3694 //     properties if none exists. Modify if it exists.
3695 //     Useful for import filters.
3696 //---------------------------------------------------------
3697 
setEndBarLineType(BarLineType val,int track,bool visible,QColor color)3698 void Measure::setEndBarLineType(BarLineType val, int track, bool visible, QColor color)
3699       {
3700       Segment* seg = undoGetSegment(SegmentType::EndBarLine, endTick());
3701       // get existing bar line for this staff, if any
3702       BarLine* bl = toBarLine(seg->element(track));
3703       if (!bl) {
3704             // no suitable bar line: create a new one
3705             bl = new BarLine(score());
3706             bl->setParent(seg);
3707             bl->setTrack(track);
3708             score()->addElement(bl);
3709             }
3710       bl->setGenerated(false);
3711       bl->setBarLineType(val);
3712       bl->setVisible(visible);
3713       bl->setColor(color.isValid() ? color : curColor());
3714       }
3715 
3716 //---------------------------------------------------------
3717 //   barLinesSetSpan
3718 //---------------------------------------------------------
3719 
barLinesSetSpan(Segment * seg)3720 void Measure::barLinesSetSpan(Segment* seg)
3721       {
3722       int track = 0;
3723       for (Staff* staff : score()->staves()) {
3724             BarLine* bl = toBarLine(seg->element(track));  // get existing bar line for this staff, if any
3725             if (bl) {
3726                   if (bl->generated()) {
3727                         bl->setSpanStaff(staff->barLineSpan());
3728                         bl->setSpanFrom(staff->barLineFrom());
3729                         bl->setSpanTo(staff->barLineTo());
3730                         }
3731                   }
3732             else {
3733                   bl = new BarLine(score());
3734                   bl->setParent(seg);
3735                   bl->setTrack(track);
3736                   bl->setGenerated(true);
3737                   bl->setSpanStaff(staff->barLineSpan());
3738                   bl->setSpanFrom(staff->barLineFrom());
3739                   bl->setSpanTo(staff->barLineTo());
3740                   bl->layout();
3741                   score()->addElement(bl);
3742                   }
3743             track += VOICES;
3744             }
3745       }
3746 
3747 //---------------------------------------------------------
3748 //   createEndBarLines
3749 //    actually creates or modifies barlines
3750 //    return the width change for measure
3751 //---------------------------------------------------------
3752 
createEndBarLines(bool isLastMeasureInSystem)3753 qreal Measure::createEndBarLines(bool isLastMeasureInSystem)
3754       {
3755       int nstaves  = score()->nstaves();
3756       Segment* seg = findSegmentR(SegmentType::EndBarLine, ticks());
3757       Measure* nm  = nextMeasure();
3758       qreal blw    = 0.0;
3759 
3760 #if 0
3761 #ifndef NDEBUG
3762       computeMinWidth();
3763 #endif
3764 #endif
3765       qreal oldWidth = width();
3766 
3767       if (nm && nm->repeatStart() && !repeatEnd() && !isLastMeasureInSystem && next() == nm) {
3768             // we may skip barline at end of a measure immediately before a start repeat:
3769             // next measure is repeat start, this measure is not a repeat end,
3770             // this is not last measure of system, no intervening frame
3771             if (!seg)
3772                   return 0.0;
3773             seg->setEnabled(false);
3774             }
3775       else {
3776             BarLineType t = nm ? BarLineType::NORMAL : BarLineType::END;
3777             if (!seg)
3778                   seg = getSegmentR(SegmentType::EndBarLine, ticks());
3779             seg->setEnabled(true);
3780             //
3781             //  Set flag "hasCourtesyKeySig" if this measure needs a courtesy key sig.
3782             //  This flag is later used to set a double end bar line and to actually
3783             //  create the courtesy key sig.
3784             //
3785 
3786             bool show = score()->styleB(Sid::genCourtesyKeysig) && !sectionBreak() && nm;
3787 
3788             setHasCourtesyKeySig(false);
3789 
3790             if (isLastMeasureInSystem && show) {
3791                   Fraction tick = endTick();
3792                   for (int staffIdx = 0; staffIdx < nstaves; ++staffIdx) {
3793                         Staff* staff     = score()->staff(staffIdx);
3794                         KeySigEvent key1 = staff->keySigEvent(tick - Fraction::fromTicks(1));
3795                         KeySigEvent key2 = staff->keySigEvent(tick);
3796                         if (!(key1 == key2)) {
3797                               // locate a key sig. in next measure and, if found,
3798                               // check if it has court. sig turned off
3799                               Segment* s = nm->findSegment(SegmentType::KeySig, tick);
3800                               if (s) {
3801                                     KeySig* ks = toKeySig(s->element(staffIdx * VOICES));
3802                                     if (ks && !ks->showCourtesy())
3803                                           continue;
3804                                     }
3805                               setHasCourtesyKeySig(true);
3806                               t = BarLineType::DOUBLE;
3807                               break;
3808                               }
3809                         }
3810                   }
3811 
3812             bool force = false;
3813             if (repeatEnd()) {
3814                   t = BarLineType::END_REPEAT;
3815                   force = true;
3816                   }
3817             else if (isLastMeasureInSystem && nextMeasure() && nextMeasure()->repeatStart()) {
3818                   t = BarLineType::NORMAL;
3819 //                  force = true;
3820                   }
3821 
3822             for (int staffIdx = 0; staffIdx < nstaves; ++staffIdx) {
3823                   int track    = staffIdx * VOICES;
3824                   BarLine* bl  = toBarLine(seg->element(track));
3825                   Staff* staff = score()->staff(staffIdx);
3826                   if (!bl) {
3827                         bl = new BarLine(score());
3828                         bl->setParent(seg);
3829                         bl->setTrack(track);
3830                         bl->setGenerated(true);
3831                         bl->setSpanStaff(staff->barLineSpan());
3832                         bl->setSpanFrom(staff->barLineFrom());
3833                         bl->setSpanTo(staff->barLineTo());
3834                         bl->setBarLineType(t);
3835                         score()->addElement(bl);
3836                         }
3837                   else {
3838                         // do not change bar line type if bar line is user modified
3839                         // and its not a repeat start/end barline (forced)
3840 
3841                         if (bl->generated()) {
3842                               bl->setSpanStaff(staff->barLineSpan());
3843                               bl->setSpanFrom(staff->barLineFrom());
3844                               bl->setSpanTo(staff->barLineTo());
3845                               bl->setBarLineType(t);
3846                               }
3847                         else {
3848                               if (bl->barLineType() != t) {
3849                                     if (force) {
3850                                           bl->undoChangeProperty(Pid::BARLINE_TYPE, QVariant::fromValue(t));
3851                                           bl->setGenerated(true);
3852                                           }
3853                                     }
3854                               }
3855                         }
3856                   bl->layout();
3857                   blw = qMax(blw, bl->width());
3858                   }
3859             // right align within segment
3860             for (int staffIdx = 0; staffIdx < nstaves; ++staffIdx) {
3861                   int track   = staffIdx * VOICES;
3862                   BarLine* bl = toBarLine(seg->element(track));
3863                   if (bl)
3864                         bl->rxpos() += blw - bl->width();
3865                   }
3866             seg->createShapes();
3867             }
3868 
3869       // set relative position of end barline and clef
3870       // if end repeat, clef goes after, otherwise clef goes before
3871       Segment* clefSeg = findSegmentR(SegmentType::Clef, ticks());
3872       if (clefSeg) {
3873             bool wasVisible = clefSeg->visible();
3874             int visibleInt = 0;
3875             for (int staffIdx = 0; staffIdx < nstaves; ++staffIdx) {
3876                   int track    = staffIdx * VOICES;
3877                   Clef* clef = toClef(clefSeg->element(track));
3878                   if (clef) {
3879                         bool showCourtesy = score()->genCourtesyClef() && clef->showCourtesy(); // normally show a courtesy clef
3880                         // check if the measure is the last measure of the system or the last measure before a frame
3881                         bool lastMeasure = isLastMeasureInSystem || (nm ? !(next() == nm) : true);
3882                         if (!nm || isFinalMeasureOfSection() || (lastMeasure && !showCourtesy)) {
3883                               // hide the courtesy clef in the final measure of a section, or if the measure is the final measure of a system
3884                               // and the score style or the clef style is set to "not show courtesy clef",
3885                               // or if the clef is at the end of the very last measure of the score
3886                               clef->clear();
3887                               clefSeg->createShape(staffIdx);
3888                               if (visibleInt == 0)
3889                                     visibleInt = 1;
3890                               }
3891                         else {
3892                               clef->layout();
3893                               clefSeg->createShape(staffIdx);
3894                               visibleInt = 2;
3895                               }
3896                         }
3897                   }
3898             if (visibleInt == 2)       // there is at least one visible clef in the clef segment
3899                   clefSeg->setVisible(true);
3900             else if (visibleInt == 1)  // all (courtesy) clefs in the clef segment are not visible
3901                   clefSeg->setVisible(false);
3902             else // should never happen
3903                   qDebug("Clef Segment without Clef elements at tick %d/%d",clefSeg->tick().numerator(),clefSeg->tick().denominator());
3904             if ((wasVisible != clefSeg->visible()) && system()) // recompute the width only if necessary
3905                   computeMinWidth();
3906             if (seg) {
3907                   Segment* s1;
3908                   Segment* s2;
3909                   if (repeatEnd()) {
3910                         s1 = seg;
3911                         s2 = clefSeg;
3912                         }
3913                   else {
3914                         s1 = clefSeg;
3915                         s2 = seg;
3916                         }
3917                   if (s1->next() != s2) {
3918                         _segments.remove(s1);
3919                         _segments.insert(s1, s2);
3920                         }
3921                   }
3922             }
3923 
3924       // fix segment layout
3925       Segment* s = seg->prevActive();
3926       if (s) {
3927             qreal x    = s->rxpos();
3928             computeMinWidth(s, x, false);
3929             }
3930 
3931 #if 0
3932 #ifndef NDEBUG
3933       qreal w = width();
3934       computeMinWidth();
3935       if (!qFuzzyCompare(w, width()))
3936             qDebug("width mismatch %f != %f at %d", w, width(), tick());
3937 #endif
3938 #endif
3939       return width() - oldWidth;
3940       }
3941 
3942 //---------------------------------------------------------
3943 //   basicStretch
3944 //---------------------------------------------------------
3945 
basicStretch() const3946 qreal Measure::basicStretch() const
3947       {
3948       qreal stretch = userStretch() * score()->styleD(Sid::measureSpacing);
3949       if (stretch < 1.0)
3950             stretch = 1.0;
3951       return stretch;
3952       }
3953 
3954 //---------------------------------------------------------
3955 //   basicWidth
3956 //---------------------------------------------------------
3957 
basicWidth() const3958 qreal Measure::basicWidth() const
3959       {
3960       Segment* ls = last();
3961       qreal w = (ls->x() + ls->width()) * basicStretch();
3962       qreal minMeasureWidth = score()->styleP(Sid::minMeasureWidth);
3963       if (w < minMeasureWidth)
3964             w = minMeasureWidth;
3965       return w;
3966       }
3967 
3968 //---------------------------------------------------------
3969 //   layoutWeight
3970 //---------------------------------------------------------
3971 
layoutWeight(int maxMMRestLength) const3972 int Measure::layoutWeight(int maxMMRestLength) const
3973       {
3974       int w = ticks().ticks();
3975       // reduce weight of mmrests
3976       // so the nominal width is not directly proportional to duration (still linear, just not 1:1)
3977       // and they are not so "greedy" in taking up available space on a system
3978       if (isMMRest()) {
3979             int timesigTicks = timesig().ticks();
3980             // TODO: style setting
3981             if (maxMMRestLength) {
3982                   int maxW = timesigTicks * maxMMRestLength;
3983                   w = qMin(w, maxW);
3984                   }
3985             w -= timesigTicks;
3986             w = timesigTicks + w / 32;
3987             }
3988       return w;
3989       }
3990 
3991 //-------------------------------------------------------------------
3992 //   addSystemHeader
3993 ///   Add elements to make this measure suitable as the first measure
3994 ///   of a system.
3995 //    The system header can contain a starting BarLine, a Clef,
3996 //    and a KeySig
3997 //-------------------------------------------------------------------
3998 
addSystemHeader(bool isFirstSystem)3999 void Measure::addSystemHeader(bool isFirstSystem)
4000       {
4001       int staffIdx = 0;
4002       Segment* kSegment = findFirstR(SegmentType::KeySig, Fraction(0,1));
4003       Segment* cSegment = findFirstR(SegmentType::HeaderClef, Fraction(0,1));
4004 
4005       for (const Staff* staff : score()->staves()) {
4006             const int track = staffIdx * VOICES;
4007 
4008             if (isFirstSystem || score()->styleB(Sid::genClef)) {
4009                   // find the clef type at the previous tick
4010                   ClefTypeList cl = staff->clefType(tick() - Fraction::fromTicks(1));
4011                   Segment* s = nullptr;
4012                   if (prevMeasure())
4013                         // look for a clef change at the end of the previous measure
4014                         s = prevMeasure()->findSegment(SegmentType::Clef, tick());
4015                   else if (isMMRest())
4016                         // look for a header clef at the beginning of the first underlying measure
4017                         s = mmRestFirst()->findFirstR(SegmentType::HeaderClef, Fraction(0,1));
4018                   if (s) {
4019                         Clef* c = toClef(s->element(track));
4020                         if (c)
4021                               cl = c->clefTypeList();
4022                         }
4023                   Clef* clef;
4024                   if (!cSegment) {
4025                         cSegment = new Segment(this, SegmentType::HeaderClef, Fraction(0,1));
4026                         cSegment->setHeader(true);
4027                         add(cSegment);
4028                         clef = 0;
4029                         }
4030                   else
4031                         clef = toClef(cSegment->element(track));
4032                   if (staff->staffType(tick())->genClef()) {
4033                         if (!clef) {
4034                               //
4035                               // create missing clef
4036                               //
4037                               clef = new Clef(score());
4038                               clef->setTrack(track);
4039                               clef->setGenerated(true);
4040                               clef->setParent(cSegment);
4041                               cSegment->add(clef);
4042                               }
4043                         if (clef->generated())
4044                               clef->setClefType(cl);
4045                         clef->setSmall(false);
4046                         clef->layout();
4047                         }
4048                   else if (clef) {
4049                         clef->parent()->remove(clef);
4050                         delete clef;
4051                         }
4052                   //cSegment->createShape(staffIdx);
4053                   cSegment->setEnabled(true);
4054                   }
4055             else {
4056                   if (cSegment)
4057                         cSegment->setEnabled(false);
4058                   }
4059 
4060             // keep key sigs in TABs: TABs themselves should hide them
4061             bool needKeysig = isFirstSystem || score()->styleB(Sid::genKeysig);
4062 
4063             // If we need a Key::C KeySig (which would be invisible) and there is
4064             // a courtesy key sig, don’t create it and switch generated flags.
4065             // This avoids creating an invisible KeySig which can distort layout.
4066 
4067             KeySigEvent keyIdx = staff->keySigEvent(tick());
4068             KeySig* ksAnnounce = 0;
4069             if (needKeysig && (keyIdx.key() == Key::C)) {
4070                   Measure* pm = prevMeasure();
4071                   if (pm && pm->hasCourtesyKeySig()) {
4072                         Segment* ks = pm->first(SegmentType::KeySigAnnounce);
4073                         if (ks) {
4074                               ksAnnounce = toKeySig(ks->element(track));
4075                               if (ksAnnounce) {
4076                                     needKeysig = false;
4077 //                                    if (keysig) {
4078 //                                          ksAnnounce->setGenerated(false);
4079 //TODO                                      keysig->setGenerated(true);
4080 //                                          }
4081                                     }
4082                               }
4083                         }
4084                   }
4085 
4086             needKeysig = needKeysig && (keyIdx.key() != Key::C || keyIdx.custom() || keyIdx.isAtonal());
4087 
4088             if (needKeysig) {
4089                   KeySig* keysig;
4090                   if (!kSegment) {
4091                         kSegment = new Segment(this, SegmentType::KeySig, Fraction(0,1));
4092                         kSegment->setHeader(true);
4093                         add(kSegment);
4094                         keysig = 0;
4095                         }
4096                   else
4097                         keysig  = toKeySig(kSegment->element(track));
4098                   if (!keysig) {
4099                         //
4100                         // create missing key signature
4101                         //
4102                         keysig = new KeySig(score());
4103                         keysig->setTrack(track);
4104                         keysig->setGenerated(true);
4105                         keysig->setParent(kSegment);
4106                         kSegment->add(keysig);
4107                         }
4108                   keysig->setKeySigEvent(keyIdx);
4109                   keysig->layout();
4110                   //kSegment->createShape(staffIdx);
4111                   kSegment->setEnabled(true);
4112                   }
4113             else {
4114                   if (kSegment && staff->isPitchedStaff(tick())) {
4115                         // do not disable user modified keysigs
4116                         bool disable = true;
4117                         for (int i = 0; i < score()->nstaves(); ++i) {
4118                               Element* e = kSegment->element(i * VOICES);
4119                               Key key = score()->staff(i)->key(tick());
4120                               if ((e && !e->generated()) || (key != keyIdx.key())) {
4121                                     disable = false;
4122                                     }
4123                               else if (e && e->generated() && key == keyIdx.key() && keyIdx.key() == Key::C){
4124                                     // If a key sig segment is disabled, it may be re-enabled if there is
4125                                     // a transposing instrument using a different key sig.
4126                                     // To prevent this from making the wrong key sig display, remove any key
4127                                     // sigs on staves where the key in this measure is C.
4128                                     kSegment->remove(e);
4129                                     }
4130                               }
4131 
4132                         if (disable)
4133                               kSegment->setEnabled(false);
4134                         else {
4135                               Element* e = kSegment->element(track);
4136                               if (e && e->isKeySig()) {
4137                                     KeySig* keysig = toKeySig(e);
4138                                     keysig->layout();
4139                                     }
4140                               }
4141                         }
4142                   }
4143 
4144             ++staffIdx;
4145             }
4146       if (cSegment)
4147             cSegment->createShapes();
4148       if (kSegment)
4149             kSegment->createShapes();
4150 
4151       //
4152       // create systemic barline
4153       //
4154       Segment* s  = findSegment(SegmentType::BeginBarLine, tick());
4155       int n       = score()->nstaves();
4156       if ((n > 1 && score()->styleB(Sid::startBarlineMultiple)) || (n == 1 && score()->styleB(Sid::startBarlineSingle))) {
4157             if (!s) {
4158                   s = new Segment(this, SegmentType::BeginBarLine, Fraction(0,1));
4159                   add(s);
4160                   }
4161             for (int track = 0; track < score()->ntracks(); track += VOICES) {
4162                   BarLine* bl = toBarLine(s->element(track));
4163                   if (!bl) {
4164                         bl = new BarLine(score());
4165                         bl->setTrack(track);
4166                         bl->setGenerated(true);
4167                         bl->setParent(s);
4168                         bl->setBarLineType(BarLineType::NORMAL);
4169                         bl->setSpanStaff(true);
4170                         bl->layout();
4171                         s->add(bl);
4172                         }
4173                   }
4174             s->createShapes();
4175             s->setEnabled(true);
4176             s->setHeader(true);
4177             setHeader(true);
4178             }
4179       else if (s)
4180             s->setEnabled(false);
4181       checkHeader();
4182       }
4183 
4184 //---------------------------------------------------------
4185 //   addSystemTrailer
4186 //---------------------------------------------------------
4187 
addSystemTrailer(Measure * nm)4188 void Measure::addSystemTrailer(Measure* nm)
4189       {
4190       Fraction _rtick = ticks();
4191       bool isFinalMeasure = isFinalMeasureOfSection();
4192 
4193       // locate a time sig. in the next measure and, if found,
4194       // check if it has court. sig. turned off
4195       TimeSig* ts = nullptr;
4196       bool showCourtesySig = false;
4197       Segment* s = findSegmentR(SegmentType::TimeSigAnnounce, _rtick);
4198       if (nm && score()->genCourtesyTimesig() && !isFinalMeasure && !score()->floatMode()) {
4199             Segment* tss = nm->findSegmentR(SegmentType::TimeSig, Fraction(0,1));
4200             if (tss) {
4201                   int nstaves = score()->nstaves();
4202                   for (int track = 0; track < nstaves * VOICES; track += VOICES) {
4203                         ts = toTimeSig(tss->element(track));
4204                         if (ts)
4205                               break;
4206                         }
4207                   if (ts && ts->showCourtesySig()) {
4208                         showCourtesySig = true;
4209                         // if due, create a new courtesy time signature for each staff
4210                         if (!s) {
4211                               s  = new Segment(this, SegmentType::TimeSigAnnounce, _rtick);
4212                               s->setTrailer(true);
4213                               add(s);
4214                               }
4215                         s->setEnabled(true);
4216                         for (int track = 0; track < nstaves * VOICES; track += VOICES) {
4217                               TimeSig* nts = toTimeSig(tss->element(track));
4218                               if (!nts)
4219                                     continue;
4220                               ts = toTimeSig(s->element(track));
4221                               if (!ts) {
4222                                     ts = new TimeSig(score());
4223                                     ts->setTrack(track);
4224                                     ts->setGenerated(true);
4225                                     ts->setParent(s);
4226                                     score()->undoAddElement(ts);
4227                                     }
4228                               ts->setFrom(nts);
4229                               ts->layout();
4230                               //s->createShape(track / VOICES);
4231                               }
4232                         s->createShapes();
4233                         }
4234                   }
4235             }
4236       if (!showCourtesySig && s) {
4237             // remove any existing time signatures
4238             s->setEnabled(false);
4239             }
4240 
4241       // courtesy key signatures, clefs
4242 
4243       int n      = score()->nstaves();
4244       bool show  = hasCourtesyKeySig();
4245       s          = findSegmentR(SegmentType::KeySigAnnounce, _rtick);
4246 
4247       Segment* clefSegment = findSegmentR(SegmentType::Clef, ticks());
4248 
4249       for (int staffIdx = 0; staffIdx < n; ++staffIdx) {
4250             int track    = staffIdx * VOICES;
4251             Staff* staff = score()->staff(staffIdx);
4252 
4253             if (show) {
4254                   if (!s) {
4255                         s = new Segment(this, SegmentType::KeySigAnnounce, _rtick);
4256                         s->setTrailer(true);
4257                         add(s);
4258                         }
4259                   KeySig* ks = toKeySig(s->element(track));
4260                   KeySigEvent key2 = staff->keySigEvent(endTick());
4261 
4262                   if (!ks) {
4263                         ks = new KeySig(score());
4264                         ks->setTrack(track);
4265                         ks->setGenerated(true);
4266                         ks->setParent(s);
4267                         s->add(ks);
4268                         }
4269                   //else if (!(ks->keySigEvent() == key2)) {
4270                   //      score()->undo(new ChangeKeySig(ks, key2, ks->showCourtesy()));
4271                   //      }
4272                   ks->setKeySigEvent(key2);
4273                   ks->layout();
4274                   //s->createShape(track / VOICES);
4275                   s->setEnabled(true);
4276                   }
4277             else {
4278                   // remove any existent courtesy key signature
4279                   if (s)
4280                         s->setEnabled(false);
4281                   }
4282             if (clefSegment) {
4283                   Clef* clef = toClef(clefSegment->element(track));
4284                   if (clef)
4285                          clef->setSmall(true);
4286                   }
4287             }
4288       if (s)
4289             s->createShapes();
4290       if (clefSegment)
4291             clefSegment->createShapes();
4292 
4293       checkTrailer();
4294       }
4295 
4296 //---------------------------------------------------------
4297 //   removeSystemHeader
4298 //---------------------------------------------------------
4299 
removeSystemHeader()4300 void Measure::removeSystemHeader()
4301       {
4302       if (!header())
4303             return;
4304       for (Segment* seg = first(); seg; seg = seg->next()) {
4305             if (!seg->header())
4306                   break;
4307             seg->setEnabled(false);
4308             }
4309       setHeader(false);
4310       }
4311 
4312 //---------------------------------------------------------
4313 //   removeSystemTrailer
4314 //---------------------------------------------------------
4315 
removeSystemTrailer()4316 void Measure::removeSystemTrailer()
4317       {
4318       bool changed = false;
4319       for (Segment* seg = last(); seg != first(); seg = seg->prev()) {
4320             if (!seg->trailer())
4321                   break;
4322             if (seg->enabled())
4323                   seg->setEnabled(false);
4324             changed = true;
4325             }
4326       setTrailer(false);
4327       if (system() && changed)
4328             computeMinWidth();
4329       }
4330 
4331 //---------------------------------------------------------
4332 //   checkHeader
4333 //---------------------------------------------------------
4334 
checkHeader()4335 void Measure::checkHeader()
4336       {
4337       for (Segment* seg = first(); seg; seg = seg->next()) {
4338             if (seg->enabled() && seg->header()) {
4339                   setHeader(seg->header());
4340                   break;
4341                   }
4342             }
4343       }
4344 
4345 //---------------------------------------------------------
4346 //   checkTrailer
4347 //---------------------------------------------------------
4348 
checkTrailer()4349 void Measure::checkTrailer()
4350       {
4351       for (Segment* seg = last(); seg != first(); seg = seg->prev()) {
4352             if (seg->enabled() && seg->trailer()) {
4353                   setTrailer(seg->trailer());
4354                   break;
4355                   }
4356             }
4357       }
4358 
4359 //---------------------------------------------------------
4360 //   setStretchedWidth
4361 //---------------------------------------------------------
4362 
setStretchedWidth(qreal w)4363 void Measure::setStretchedWidth(qreal w)
4364       {
4365       qreal minWidth = isMMRest() ? score()->styleP(Sid::minMMRestWidth) : score()->styleP(Sid::minMeasureWidth);
4366       if (w < minWidth)
4367             w = minWidth;
4368 
4369       qreal stretchableWidth = 0.0;
4370       for (Segment* s = first(SegmentType::ChordRest); s; s = s->next(SegmentType::ChordRest)) {
4371             if (!s->enabled())
4372                   continue;
4373             stretchableWidth += s->width();
4374             }
4375       const int maxMMRestLength = 32;     // TODO: style
4376       int weight = layoutWeight(maxMMRestLength);
4377       w += stretchableWidth * (basicStretch() - 1.0) * weight / 1920.0;
4378 
4379       setWidth(w);
4380       }
4381 
4382 //---------------------------------------------------------
4383 //   hasAccidental
4384 //---------------------------------------------------------
4385 
hasAccidental(Segment * s)4386 static bool hasAccidental(Segment* s)
4387       {
4388       Score* score = s->score();
4389       for (int track = 0; track < s->score()->ntracks(); ++track) {
4390             Staff* staff = score->staff(track2staff(track));
4391             if (!staff->show())
4392                   continue;
4393             Element* e = s->element(track);
4394             if (!e || !e->isChord())
4395                   continue;
4396             Chord* c = toChord(e);
4397             for (Note* n : c->notes()) {
4398                   if (n->accidental() && n->accidental()->addToSkyline())
4399                         return true;
4400                   }
4401             }
4402       return false;
4403       }
4404 
4405 //---------------------------------------------------------
4406 //   computeMinWidth
4407 //    sets the minimum stretched width of segment list s
4408 //    set the width and x position for all segments
4409 //---------------------------------------------------------
4410 
computeMinWidth(Segment * s,qreal x,bool isSystemHeader)4411 void Measure::computeMinWidth(Segment* s, qreal x, bool isSystemHeader)
4412       {
4413       Segment* fs = firstEnabled();
4414       if (!fs->visible())           // first enabled could be a clef change on invisible staff
4415             fs = fs->nextActive();
4416       bool first  = isFirstInSystem();
4417       const Shape ls(first ? QRectF(0.0, -1000000.0, 0.0, 2000000.0) : QRectF(0.0, 0.0, 0.0, spatium() * 4));
4418 
4419       if (isMMRest()) {
4420             // Reset MM rest to initial size and position
4421             Segment* seg = findSegmentR(SegmentType::ChordRest, Fraction(0,1));
4422             const int nstaves = score()->nstaves();
4423             for (int st = 0; st < nstaves; ++st) {
4424                   Rest* mmRest = toRest(seg->element(staff2track(st)));
4425                   if (mmRest) {
4426                         mmRest->rxpos() = 0;
4427                         mmRest->layoutMMRest(score()->styleP(Sid::minMMRestWidth) * mag());
4428                         mmRest->segment()->createShapes();
4429                         }
4430                   }
4431             }
4432 
4433       while (s) {
4434             s->rxpos() = x;
4435             // skip disabled / invisible segments
4436             // segments with all elements invisible are skipped,
4437             // but only for headers or segments later in the measure -
4438             // invisible key or time signatures at the beginning of non-header measures are treated normally here
4439             // otherwise we would not allocate enough space for the first note
4440             // as it is, this isn't quite right as the space will be given by key or time margins,
4441             // not the bar to note distance
4442             // TODO: skip these segments entirely and get the correct bar to note distance
4443             if (!s->enabled() || !s->visible() || ((header() || s->rtick().isNotZero()) && s->allElementsInvisible())) {
4444                   s->setWidth(0);
4445                   s = s->next();
4446                   continue;
4447                   }
4448             Segment* ns = s->nextActive();
4449             while (ns && ((header() || ns->rtick().isNotZero()) && ns->allElementsInvisible()))
4450                   ns = ns->nextActive();
4451             // end barline might be disabled
4452             // but still consider it for spacing of previous segment
4453             if (!ns)
4454                   ns = s->next(SegmentType::BarLineType);
4455             qreal w;
4456 
4457             if (ns) {
4458                   if (isSystemHeader && (ns->isChordRestType() || (ns->isClefType() && !ns->header()))) {
4459                         // this is the system header gap
4460                         w = s->minHorizontalDistance(ns, true);
4461                         isSystemHeader = false;
4462                         }
4463                   else {
4464                         w = s->minHorizontalDistance(ns, false);
4465                         }
4466 // printf("  min %f <%s>(%d) <%s>(%d)\n", s->x(), s->subTypeName(), s->enabled(), ns->subTypeName(), ns->enabled());
4467 #if 1
4468                   // look back for collisions with previous segments
4469                   // this is time consuming (ca. +5%) and probably requires more optimization
4470 
4471                   if (s == fs) // don't let the second segment cross measure start (not covered by the loop below)
4472                         w = std::max(w, ns->minLeft(ls) - s->x());
4473 
4474                   int n = 1;
4475                   for (Segment* ps = s; ps != fs;) {
4476                         qreal ww;
4477                         ps = ps->prevActive();
4478 
4479                         Q_ASSERT(ps); // ps should never be nullptr but better be safe.
4480                         if (!ps)
4481                               break;
4482 
4483                         if (ps->isChordRestType())
4484                               ++n;
4485                         ww = ps->minHorizontalCollidingDistance(ns) - (s->x() - ps->x());
4486 
4487                         if (ps == fs)
4488                               ww = std::max(ww, ns->minLeft(ls) - s->x());
4489                         if (ww > w) {
4490                               // overlap !
4491                               // distribute extra space between segments ps - ss;
4492                               // only ChordRest segments get more space
4493                               // TODO: is there a special case n == 0 ?
4494 
4495                               qreal d = (ww - w) / n;
4496                               qreal xx = ps->x();
4497                               for (Segment* ss = ps; ss != s;) {
4498                                     Segment* ns1 = ss->nextActive();
4499                                     qreal ww1    = ss->width();
4500                                     if (ss->isChordRestType()) {
4501                                           ww1 += d;
4502                                           ss->setWidth(ww1);
4503                                           }
4504                                     xx += ww1;
4505                                     ns1->rxpos() = xx;
4506                                     ss = ns1;
4507                                     }
4508                               w += d;
4509                               x = xx;
4510                               break;
4511                               }
4512                         }
4513 #endif
4514                   }
4515             else
4516                   w = s->minRight();
4517             s->setWidth(w);
4518             x += w;
4519             s = s->next();
4520             }
4521       setStretchedWidth(x);
4522       }
4523 
computeMinWidth()4524 void Measure::computeMinWidth()
4525       {
4526       Segment* s;
4527 
4528       //
4529       // skip disabled segment
4530       //
4531       // TODO: skip segments with all elements invisible also
4532       // this will eventually allow us to calculate correct bar to note distance
4533       // even if there is an invisible key or time signature present
4534       for (s = first(); s && !s->enabled(); s = s->next()) {
4535             s->rxpos() = 0;
4536             s->setWidth(0);
4537             }
4538       if (!s) {
4539             setWidth(0.0);
4540             return;
4541             }
4542       qreal x;
4543       bool first = isFirstInSystem();
4544 
4545       // left barriere:
4546       //    Make sure no elements crosses the left boarder if first measure in a system.
4547       //
4548       Shape ls(first ? QRectF(0.0, -1000000.0, 0.0, 2000000.0) : QRectF(0.0, 0.0, 0.0, spatium() * 4));
4549 
4550       x = s->minLeft(ls);
4551 
4552       if (s->isStartRepeatBarLineType()) {
4553             System*  sys = system();
4554             MeasureBase* pmb = prev();
4555             if (pmb->isMeasure() && pmb->system() == sys && pmb->repeatEnd()) {
4556                   Segment* seg = toMeasure(pmb)->last();
4557                   // overlap end repeat barline with start repeat barline
4558                   if (seg->isEndBarLineType())
4559                         x -= score()->styleP(Sid::endBarWidth) * mag();
4560                   }
4561             }
4562 
4563       if (s->isChordRestType())
4564             x += score()->styleP(hasAccidental(s) ? Sid::barAccidentalDistance : Sid::barNoteDistance);
4565       else if (s->isClefType() || s->isHeaderClefType())
4566             x += score()->styleP(Sid::clefLeftMargin);
4567       else if (s->isKeySigType())
4568             x = qMax(x, score()->styleP(Sid::keysigLeftMargin));
4569       else if (s->isTimeSigType())
4570             x = qMax(x, score()->styleP(Sid::timesigLeftMargin));
4571       x += s->extraLeadingSpace().val() * spatium();
4572       bool isSystemHeader = s->header();
4573 
4574       computeMinWidth(s, x, isSystemHeader);
4575       }
4576 
4577 }
4578