1 //=============================================================================
2 //  MuseScore
3 //  Music Composition & Notation
4 //
5 //  Copyright (C) 2002-2012 Werner Schweer
6 //
7 //  This program is free software; you can redistribute it and/or modify
8 //  it under the terms of the GNU General Public License version 2
9 //  as published by the Free Software Foundation and appearing in
10 //  the file LICENCE.GPL
11 //=============================================================================
12 
13 #include "note.h"
14 #include "rest.h"
15 #include "chord.h"
16 #include "key.h"
17 #include "sig.h"
18 #include "clef.h"
19 #include "score.h"
20 #include "slur.h"
21 #include "tie.h"
22 #include "hairpin.h"
23 #include "segment.h"
24 #include "staff.h"
25 #include "part.h"
26 #include "timesig.h"
27 #include "page.h"
28 #include "barline.h"
29 #include "tuplet.h"
30 #include "lyrics.h"
31 #include "image.h"
32 #include "keysig.h"
33 #include "beam.h"
34 #include "utils.h"
35 #include "harmony.h"
36 #include "system.h"
37 #include "navigate.h"
38 #include "articulation.h"
39 #include "drumset.h"
40 #include "measure.h"
41 #include "undo.h"
42 #include "tupletmap.h"
43 #include "tiemap.h"
44 #include "stem.h"
45 #include "iname.h"
46 #include "range.h"
47 #include "hook.h"
48 #include "repeat.h"
49 #include "textframe.h"
50 #include "accidental.h"
51 #include "ottava.h"
52 #include "instrchange.h"
53 #include "bracket.h"
54 #include "excerpt.h"
55 #include "breath.h"
56 #include "glissando.h"
57 #include "fermata.h"
58 
59 namespace Ms {
60 
61 //---------------------------------------------------------
62 //   getSelectedNote
63 //---------------------------------------------------------
64 
getSelectedNote()65 Note* Score::getSelectedNote()
66       {
67       Element* el = selection().element();
68       if (el && el->isNote())
69             return toNote(el);
70       MScore::setError(NO_NOTE_SELECTED);
71       return 0;
72       }
73 
74 //---------------------------------------------------------
75 //   getSelectedChordRest
76 //---------------------------------------------------------
77 
getSelectedChordRest() const78 ChordRest* Score::getSelectedChordRest() const
79       {
80       Element* el = selection().element();
81       if (el) {
82             if (el->isNote())
83                   return toNote(el)->chord();
84             else if (el->isRest() || el->isRepeatMeasure())
85                   return toRest(el);
86             else if (el->isChord())
87                   return toChord(el);
88             }
89       MScore::setError(NO_NOTE_REST_SELECTED);
90       return 0;
91       }
92 
93 //---------------------------------------------------------
94 //   getSelectedChordRest2
95 //---------------------------------------------------------
96 
getSelectedChordRest2(ChordRest ** cr1,ChordRest ** cr2) const97 void Score::getSelectedChordRest2(ChordRest** cr1, ChordRest** cr2) const
98       {
99       *cr1 = 0;
100       *cr2 = 0;
101       for (Element* e : selection().elements()) {
102             if (e->isNote())
103                   e = e->parent();
104             if (e->isChordRest()) {
105                   ChordRest* cr = toChordRest(e);
106                   if (*cr1 == 0 || (*cr1)->tick() > cr->tick())
107                         *cr1 = cr;
108                   if (*cr2 == 0 || (*cr2)->tick() < cr->tick())
109                         *cr2 = cr;
110                   }
111             }
112       if (*cr1 == 0)
113             MScore::setError(NO_NOTE_REST_SELECTED);
114       if (*cr1 == *cr2)
115             *cr2 = 0;
116       }
117 
118 //---------------------------------------------------------
119 //   getSelectedChordRests
120 //---------------------------------------------------------
121 
getSelectedChordRests() const122 QSet<ChordRest*> Score::getSelectedChordRests() const
123       {
124       QSet<ChordRest*> set;
125       for (Element* e : selection().elements()) {
126             if (e->isNote())
127                   e = e->parent();
128             if (e->isChordRest()) {
129                   set.insert(toChordRest(e));
130                   }
131             }
132       return set;
133       }
134 
135 //---------------------------------------------------------
136 //   pos
137 //---------------------------------------------------------
138 
pos()139 Fraction Score::pos()
140       {
141       Element* el = selection().element();
142       if (selection().activeCR())
143             el = selection().activeCR();
144       if (el) {
145             switch (el->type()) {
146                   case ElementType::NOTE:
147                         el = el->parent();
148                         // fall through
149                   case ElementType::REPEAT_MEASURE:
150                   case ElementType::REST:
151                   case ElementType::CHORD:
152                         return toChordRest(el)->tick();
153                   default:
154                         break;
155                   }
156             }
157       return Fraction(-1, 1);
158       }
159 
160 //---------------------------------------------------------
161 //   addRest
162 //    create one Rest at tick with duration d
163 //    create segment if necessary
164 //---------------------------------------------------------
165 
addRest(const Fraction & tick,int track,TDuration d,Tuplet * tuplet)166 Rest* Score::addRest(const Fraction& tick, int track, TDuration d, Tuplet* tuplet)
167       {
168       Measure* measure = tick2measure(tick);
169       Rest* rest       = new Rest(this, d);
170       if (d.type() == TDuration::DurationType::V_MEASURE)
171             rest->setTicks(measure->stretchedLen(staff(track/VOICES)));
172       else
173             rest->setTicks(d.fraction());
174       rest->setTrack(track);
175       rest->setTuplet(tuplet);
176       undoAddCR(rest, measure, tick);
177       return rest;
178       }
179 
180 //---------------------------------------------------------
181 //   addRest
182 //---------------------------------------------------------
183 
addRest(Segment * s,int track,TDuration d,Tuplet * tuplet)184 Rest* Score::addRest(Segment* s, int track, TDuration d, Tuplet* tuplet)
185       {
186       Rest* rest = new Rest(this, d);
187       if (d.type() == TDuration::DurationType::V_MEASURE)
188             rest->setTicks(s->measure()->stretchedLen(staff(track/VOICES)));
189       else
190             rest->setTicks(d.fraction());
191       rest->setTrack(track);
192       rest->setParent(s);
193       rest->setTuplet(tuplet);
194       undoAddCR(rest, tick2measure(s->tick()), s->tick());
195       return rest;
196       }
197 
198 //---------------------------------------------------------
199 //   addChord
200 //    Create one Chord at tick with duration d
201 //    - create segment if necessary.
202 //    - Use chord "oc" as prototype;
203 //    - if "genTie" then tie to chord "oc"
204 //---------------------------------------------------------
205 
addChord(const Fraction & tick,TDuration d,Chord * oc,bool genTie,Tuplet * tuplet)206 Chord* Score::addChord(const Fraction& tick, TDuration d, Chord* oc, bool genTie, Tuplet* tuplet)
207       {
208       Measure* measure = tick2measure(tick);
209       if (measure->endTick() <= tick) {
210             qDebug("Score::addChord(): end of score?");
211             return 0;
212             }
213 
214       Chord* chord = new Chord(this);
215       chord->setTuplet(tuplet);
216       chord->setTrack(oc->track());
217       chord->setDurationType(d);
218       chord->setTicks(d.fraction());
219 
220       for (Note* n : oc->notes()) {
221             Note* nn = new Note(this);
222             nn->setPitch(n->pitch());
223             nn->setTpc1(n->tpc1());
224             nn->setTpc2(n->tpc2());
225             chord->add(nn);
226             }
227       undoAddCR(chord, measure, tick);
228 
229       //
230       // now as both chords are in place
231       // (have segments as parent) we can add ties:
232       //
233       if (genTie) {
234             size_t n = oc->notes().size();
235             for(size_t i = 0; i < n; ++i) {
236                   Note* n1  = oc->notes()[i];
237                   Note* n2 = chord->notes()[i];
238                   Tie* tie = new Tie(this);
239                   tie->setStartNote(n1);
240                   tie->setEndNote(n2);
241                   tie->setTick(tie->startNote()->tick());
242                   tie->setTick2(tie->endNote()->tick());
243                   tie->setTrack(n1->track());
244                   undoAddElement(tie);
245                   }
246             }
247 
248       return chord;
249       }
250 
251 //---------------------------------------------------------
252 //   addClone
253 //---------------------------------------------------------
254 
addClone(ChordRest * cr,const Fraction & tick,const TDuration & d)255 ChordRest* Score::addClone(ChordRest* cr, const Fraction& tick, const TDuration& d)
256       {
257       ChordRest* newcr;
258       // change a RepeatMeasure() into an Rest()
259       if (cr->isRepeatMeasure())
260             newcr = new Rest(*toRest(cr));
261       else
262             newcr = toChordRest(cr->clone());
263       newcr->rxpos() = 0.0;
264       newcr->setDurationType(d);
265       newcr->setTicks(d.fraction());
266       newcr->setTuplet(cr->tuplet());
267       newcr->setSelected(false);
268 
269       undoAddCR(newcr, cr->measure(), tick);
270       return newcr;
271       }
272 
273 //---------------------------------------------------------
274 //   setRest
275 //    create one or more rests to fill "l"
276 //---------------------------------------------------------
277 
setRest(const Fraction & _tick,int track,const Fraction & _l,bool useDots,Tuplet * tuplet,bool useFullMeasureRest)278 Rest* Score::setRest(const Fraction& _tick, int track, const Fraction& _l, bool useDots, Tuplet* tuplet, bool useFullMeasureRest)
279       {
280       Fraction l       = _l;
281       Fraction tick    = _tick;
282       Measure* measure = tick2measure(tick);
283       Rest* r          = 0;
284       Staff* staff     = Score::staff(track / VOICES);
285 
286       while (!l.isZero()) {
287             //
288             // divide into measures
289             //
290             Fraction f;
291             if (tuplet) {
292                   f = tuplet->baseLen().fraction() * tuplet->ratio().numerator();
293                   for (DurationElement* de : tuplet->elements()) {
294                         if (de->tick() >= tick)
295                               break;
296                         f -= de->ticks();
297                         }
298                   //
299                   // restrict to tuplet len
300                   //
301                   if (f < l)
302                         l = f;
303                   }
304             else {
305                   if (measure->tick() < tick)
306                         f = measure->tick() + measure->ticks() - tick;
307                   else
308                         f = measure->ticks();
309                   f *= staff->timeStretch(tick);
310                   }
311 
312             if (f > l)
313                   f = l;
314 
315             if ((track % VOICES) && !measure->hasVoice(track) && (tick == measure->tick())) {
316                   l -= f;
317                   measure = measure->nextMeasure();
318                   if (!measure)
319                         break;
320                   tick = measure->tick();
321                   continue;
322                   }
323 
324             if ((measure->timesig() == measure->ticks())   // not in pickup measure
325                && (measure->tick() == tick)
326                && (measure->stretchedLen(staff) == f)
327                && !tuplet
328                && (useFullMeasureRest)) {
329                   Rest* rest = addRest(tick, track, TDuration(TDuration::DurationType::V_MEASURE), tuplet);
330                   tick += rest->actualTicks();
331                   if (r == 0)
332                         r = rest;
333                   }
334             else {
335                   //
336                   // compute list of durations which will fit l
337                   //
338                   std::vector<TDuration> dList;
339                   if (tuplet || staff->isLocalTimeSignature(tick)) {
340                         dList = toDurationList(l, useDots);
341                         std::reverse(dList.begin(), dList.end());
342                         }
343                   else {
344                         dList = toRhythmicDurationList(f, true, tick - measure->tick(), sigmap()->timesig(tick).nominal(), measure, useDots ? 1 : 0);
345                         }
346                   if (dList.empty())
347                         return 0;
348 
349                   Rest* rest = 0;
350                   for (const TDuration& d : dList) {
351                         rest = addRest(tick, track, d, tuplet);
352                         if (r == 0)
353                               r = rest;
354                         tick += rest->actualTicks();
355                         }
356                   }
357             l -= f;
358 
359             measure = measure->nextMeasure();
360             if (!measure)
361                   break;
362             tick = measure->tick();
363             }
364       return r;
365       }
366 
367 //---------------------------------------------------------
368 //   addNote from NoteVal
369 //---------------------------------------------------------
370 
addNote(Chord * chord,const NoteVal & noteVal,bool forceAccidental,InputState * externalInputState)371 Note* Score::addNote(Chord* chord, const NoteVal& noteVal, bool forceAccidental, InputState* externalInputState)
372       {
373       InputState& is = externalInputState ? (*externalInputState) : _is;
374 
375       Note* note = new Note(this);
376       note->setParent(chord);
377       note->setTrack(chord->track());
378       note->setNval(noteVal);
379       undoAddElement(note);
380       if (forceAccidental) {
381             int tpc = styleB(Sid::concertPitch) ? noteVal.tpc1 : noteVal.tpc2;
382             AccidentalVal alter = tpc2alter(tpc);
383             AccidentalType at = Accidental::value2subtype(alter);
384             Accidental* a = new Accidental(this);
385             a->setAccidentalType(at);
386             a->setRole(AccidentalRole::USER);
387             a->setParent(note);
388             undoAddElement(a);
389             }
390       setPlayNote(true);
391       setPlayChord(true);
392 
393       if (externalInputState) {
394             is.setTrack(note->track());
395             is.setLastSegment(is.segment());
396             is.setSegment(note->chord()->segment());
397             }
398       else {
399             select(note, SelectType::SINGLE, 0);
400             }
401 
402       if (!chord->staff()->isTabStaff(chord->tick())) {
403             NoteEntryMethod entryMethod = is.noteEntryMethod();
404             if (entryMethod != NoteEntryMethod::REALTIME_AUTO && entryMethod != NoteEntryMethod::REALTIME_MANUAL)
405                   is.moveToNextInputPos();
406             }
407       return note;
408       }
409 
410 //---------------------------------------------------------
411 //   rewriteMeasures
412 //    rewrite all measures from fm to lm (including)
413 //    If staffIdx is valid (>= 0), then rewrite a local
414 //    timesig change.
415 //---------------------------------------------------------
416 
rewriteMeasures(Measure * fm,Measure * lm,const Fraction & ns,int staffIdx)417 bool Score::rewriteMeasures(Measure* fm, Measure* lm, const Fraction& ns, int staffIdx)
418       {
419       if (staffIdx >= 0) {
420             // local timesig
421             // don't actually rewrite, just update measure rest durations
422             // abort if there is anything other than measure rests in range
423             int strack = staffIdx * VOICES;
424             int etrack = strack + VOICES;
425             for (Measure* m = fm; ; m = m->nextMeasure()) {
426                   for (Segment* s = m->first(SegmentType::ChordRest); s; s = s->next(SegmentType::ChordRest)) {
427                         for (int track = strack; track < etrack; ++track) {
428                               ChordRest* cr = toChordRest(s->element(track));
429                               if (!cr)
430                                     continue;
431                               if (cr->isRest() && cr->durationType() == TDuration::DurationType::V_MEASURE)
432                                     cr->undoChangeProperty(Pid::DURATION, QVariant::fromValue(ns));
433                               else
434                                     return false;
435                               }
436                         }
437                   if (m == lm)
438                         break;
439                   }
440             return true;
441             }
442       int measures = 1;
443       bool fmr     = true;
444 
445       // Format: chord 1 tick, chord 2 tick, tremolo, track
446       std::vector<std::tuple<Fraction, Fraction, Tremolo*, int>> tremoloChordTicks;
447 
448       int strack, etrack;
449       if (staffIdx < 0) {
450             strack = 0;
451             etrack = ntracks();
452             }
453       else {
454             strack = staffIdx * VOICES;
455             etrack = strack + VOICES;
456             }
457 
458       for (Measure* m = fm; m; m = m->nextMeasure()) {
459             if (!m->isFullMeasureRest())
460                   fmr = false;
461 
462             for (Segment* s = m->first(SegmentType::ChordRest); s; s = s->next(SegmentType::ChordRest)) {
463                   for (int track = strack; track < etrack; ++track) {
464                         ChordRest* cr = toChordRest(s->element(track));
465                         if (cr && cr->isChord()) {
466                               Chord* chord = toChord(cr);
467                               if (chord->tremolo() && chord->tremolo()->twoNotes()) {
468                                     Tremolo* trem = chord->tremolo();
469 
470                                     // Don't add same chord twice
471                                     if (trem->chord2() == chord)
472                                           continue;
473                                     auto newP = std::tuple<Fraction, Fraction, Tremolo*, int>(cr->tick(), trem->chord2()->segment()->tick(), trem, track);
474                                     tremoloChordTicks.push_back(newP);
475                                     }
476                               }
477                         }
478                   }
479 
480             if (m == lm)
481                   break;
482             ++measures;
483             }
484 
485       if (!fmr) {
486             // check for local time signatures
487             for (Measure* m = fm; m; m = m -> nextMeasure()) {
488                   for (int si = 0; si < nstaves(); ++si) {
489                         if (staff(si)->timeStretch(m->tick()) != Fraction(1,1)) {
490                               // we cannot change a staff with a local time signature
491                               return false;
492                               }
493                         if (m == lm)
494                               break;
495                         }
496                   }
497             }
498 
499       ScoreRange range;
500       range.read(fm->first(), lm->last());
501 
502       //
503       // calculate number of required measures = nm
504       //
505       Fraction k = range.ticks() / ns;
506       int nm     = (k.numerator() + k.denominator() - 1)/ k.denominator();
507 
508       Fraction nd = ns * Fraction(nm,1);
509 
510       // evtl. we have to fill the last measure
511       Fraction fill = nd - range.ticks();
512       range.fill(fill);
513 
514       for (Score* s : scoreList()) {
515             Measure* m1 = s->tick2measure(fm->tick());
516             Measure* m2 = s->tick2measure(lm->tick());
517 
518             Fraction tick1 = m1->tick();
519             Fraction tick2 = m2->endTick();
520             auto spanners = s->spannerMap().findOverlapping(tick1.ticks(), tick2.ticks());
521             for (auto i : spanners) {
522                   if (i.value->tick() >= tick1)
523                         undo(new RemoveElement(i.value));
524                   }
525             s->undoRemoveMeasures(m1, m2, true);
526 
527             Measure* nfm = 0;
528             Measure* nlm = 0;
529             Fraction tick     = { 0, 1};
530             for (int i = 0; i < nm; ++i) {
531                   Measure* m = new Measure(s);
532                   m->setPrev(nlm);
533                   if (nlm)
534                         nlm->setNext(m);
535                   m->setTimesig(ns);
536                   m->setTicks(ns);
537                   m->setTick(tick);
538                   tick += m->ticks();
539                   nlm = m;
540                   if (nfm == 0)
541                         nfm = m;
542                   }
543 //            nlm->setEndBarLineType(m2->endBarLineType(), m2->endBarLineGenerated(),
544 //               m2->endBarLineVisible(), m2->endBarLineColor());
545             //
546             // insert new calculated measures
547             //
548             nfm->setPrev(m1->prev());
549             nlm->setNext(m2->next());
550             s->undo(new InsertMeasures(nfm, nlm));
551             }
552       if (!fill.isZero())
553             undoInsertTime(lm->endTick(), fill);
554 
555       if (!range.write(masterScore(), fm->tick()))
556             return false;
557       connectTies(true);
558 
559       // Attempt to move tremolos to correct chords
560       for (auto tremPair : tremoloChordTicks) {
561             Fraction chord1Tick = std::get<0>(tremPair);
562             Fraction chord2Tick = std::get<1>(tremPair);
563             Tremolo* trem       = std::get<2>(tremPair);
564             int      track      = std::get<3>(tremPair);
565 
566             undo(new MoveTremolo(trem->score(), chord1Tick, chord2Tick, trem, track));
567             }
568 
569       if (noteEntryMode()) {
570             // set input cursor to possibly re-written segment
571             Fraction icTick = inputPos();
572             Segment* icSegment = tick2segment(icTick, false, SegmentType::ChordRest);
573             if (!icSegment) {
574                   // this can happen if cursor was on a rest
575                   // and in the rewriting it got subsumed into a full measure rest
576                   Measure* icMeasure = tick2measure(icTick);
577                   if (!icMeasure)                     // shouldn't happen, but just in case
578                         icMeasure = firstMeasure();
579                   icSegment = icMeasure->first(SegmentType::ChordRest);
580                   }
581             inputState().setSegment(icSegment);
582             }
583 
584       return true;
585       }
586 
587 //---------------------------------------------------------
588 //   rewriteMeasures
589 //    rewrite all measures up to the next time signature or section break
590 //---------------------------------------------------------
591 
rewriteMeasures(Measure * fm,const Fraction & ns,int staffIdx)592 bool Score::rewriteMeasures(Measure* fm, const Fraction& ns, int staffIdx)
593       {
594       Measure* lm  = fm;
595       Measure* fm1 = fm;
596       Measure* nm  = nullptr;
597       LayoutBreak* sectionBreak = nullptr;
598 
599       // disable local time sig modifications in linked staves
600       if (staffIdx != -1 && excerpts().size() > 0) {
601             MScore::setError(CANNOT_CHANGE_LOCAL_TIMESIG);
602             return false;
603             }
604 
605       //
606       // split into Measure segments fm-lm
607       //
608       for (MeasureBase* measure = fm; ; measure = measure->next()) {
609 
610             if (!measure || !measure->isMeasure() || lm->sectionBreak()
611               || (toMeasure(measure)->first(SegmentType::TimeSig) && measure != fm))
612                   {
613 
614                   // save section break to reinstate after rewrite
615                   if (lm->sectionBreak())
616                         sectionBreak = new LayoutBreak(*lm->sectionBreakElement());
617 
618                   if (!rewriteMeasures(fm1, lm, ns, staffIdx)) {
619                         if (staffIdx >= 0) {
620                               MScore::setError(CANNOT_CHANGE_LOCAL_TIMESIG);
621                               // restore measure rests that were prematurely modified
622                               Fraction fr(staff(staffIdx)->timeSig(fm->tick())->sig());
623                               for (Measure* m = fm1; m; m = m->nextMeasure()) {
624                                     ChordRest* cr = m->findChordRest(m->tick(), staffIdx * VOICES);
625                                     if (cr && cr->isRest() && cr->durationType() == TDuration::DurationType::V_MEASURE)
626                                           cr->undoChangeProperty(Pid::DURATION, QVariant::fromValue(fr));
627                                     else
628                                           break;
629                                     }
630                               }
631                         else {
632                               // this can be hit for local time signatures as well
633                               // (if we are rewriting all staves, but one has a local time signature)
634                               // TODO: detect error conditions better, have clearer error messages
635                               // and perform necessary fixups
636                               MScore::setError(TUPLET_CROSSES_BAR);
637                               }
638                         for (Measure* m = fm1; m; m = m->nextMeasure()) {
639                               if (m->first(SegmentType::TimeSig))
640                                     break;
641                               Fraction fr(ns);
642                               m->undoChangeProperty(Pid::TIMESIG_NOMINAL, QVariant::fromValue(fr));
643                               }
644                         return false;
645                         }
646 
647                   // after rewrite, lm is not necessarily valid
648                   // m is first MeasureBase after rewritten range
649                   // m->prevMeasure () is new last measure of range
650                   // set nm to first true Measure after rewritten range
651                   // we may use this to reinstate time signatures
652                   if (measure && measure->prevMeasure())
653                         nm = measure->prevMeasure()->nextMeasure();
654                   else
655                         nm = nullptr;
656 
657                   if (sectionBreak) {
658                         // reinstate section break, then stop rewriting
659                         if (measure && measure->prevMeasure()) {
660                               sectionBreak->setParent(measure->prevMeasure());
661                               undoAddElement(sectionBreak);
662                               }
663                         else if (!measure) {
664                               sectionBreak->setParent(lastMeasure());
665                               undoAddElement(sectionBreak);
666                               }
667                         else {
668                               qDebug("unable to restore section break");
669                               nm = nullptr;
670                               sectionBreak = nullptr;
671                               }
672                         break;
673                         }
674 
675                   // stop rewriting at end of score
676                   // or at a measure (which means we found a time signature segment)
677                   if (!measure || measure->isMeasure())
678                         break;
679 
680                   // skip frames
681                   while (!measure->isMeasure()) {
682                         if (measure->sectionBreak()) {
683                               // frame has a section break; we can stop skipping ahead
684                               sectionBreak = measure->sectionBreakElement();
685                               break;
686                               }
687                         measure = measure->next();
688                         if (!measure)
689                               break;
690                         }
691                   // stop rewriting if we encountered a section break on a frame
692                   // or if there is a time signature on first measure after the frame
693                   if (sectionBreak || (measure && toMeasure(measure)->first(SegmentType::TimeSig)))
694                         break;
695 
696                   // set up for next range to rewrite
697                   fm1 = toMeasure(measure);
698                   if (fm1 == 0)
699                         break;
700                   }
701 
702             // if we didn't break the loop already,
703             // we must have an ordinary measure
704             // add measure to range to rewrite
705             lm = toMeasure(measure);
706             }
707 
708       // if any staves don't have time signatures at the point where we stopped,
709       // we need to reinstate their previous time signatures
710       if (!nm)
711             return true;
712       Segment* s = nm->undoGetSegment(SegmentType::TimeSig, nm->tick());
713       for (int i = 0; i < nstaves(); ++i) {
714             if (!s->element(i * VOICES)) {
715                   TimeSig* ots = staff(i)->timeSig(nm->tick());
716                   if (ots) {
717                         TimeSig* nts = new TimeSig(*ots);
718                         nts->setParent(s);
719                         if (sectionBreak) {
720                               nts->setGenerated(false);
721                               nts->setShowCourtesySig(false);
722                               }
723                         undoAddElement(nts);
724                         }
725                   }
726             }
727 
728       return true;
729       }
730 
731 //---------------------------------------------------------
732 //   cmdAddTimeSig
733 //
734 //    Add or change time signature at measure in response
735 //    to gui command (drop timesig on measure or timesig)
736 //---------------------------------------------------------
737 
cmdAddTimeSig(Measure * fm,int staffIdx,TimeSig * ts,bool local)738 void Score::cmdAddTimeSig(Measure* fm, int staffIdx, TimeSig* ts, bool local)
739       {
740       deselectAll();
741 
742       if (fm->isMMRest())
743             fm = fm->mmRestFirst();
744 
745       Fraction ns   = ts->sig();
746       Fraction tick = fm->tick();
747       TimeSig* lts  = staff(staffIdx)->timeSig(tick);
748       if (local) {
749             Fraction stretch = (ns / fm->timesig()).reduced();
750             ts->setStretch(stretch);
751             }
752 
753       Fraction stretch;
754       Fraction lsig;                // last signature
755       if (lts) {
756             stretch = lts->stretch();
757             lsig    = lts->sig();
758             }
759       else {
760             stretch.set(1,1);
761             lsig.set(4,4);          // set to default
762             }
763 
764       int track    = staffIdx * VOICES;
765       Segment* seg = fm->undoGetSegment(SegmentType::TimeSig, tick);
766       TimeSig* ots = toTimeSig(seg->element(track));
767 
768       if (ots && (*ots == *ts)) {
769             //
770             //  ignore if there is already a timesig
771             //  with same values
772             //
773             delete ts;
774             return;
775             }
776 
777       auto getStaffIdxRange = [this, local, staffIdx](const Score* score) -> std::pair<int /*start*/, int /*end*/> {
778             int startStaffIdx, endStaffIdx;
779             if (local) {
780                   if (score == this) {
781                         startStaffIdx = staffIdx;
782                         endStaffIdx   = startStaffIdx + 1;
783                         }
784                   else {
785                         // TODO: get index for this score
786                         qDebug("cmdAddTimeSig: unable to write local time signature change to linked score");
787                         startStaffIdx = 0;
788                         endStaffIdx   = 0;
789                         }
790                   }
791             else {
792                   startStaffIdx = 0;
793                   endStaffIdx   = score->nstaves();
794                   }
795             return std::make_pair(startStaffIdx, endStaffIdx);
796             };
797 
798       if (ots && ots->sig() == ns && ots->stretch() == ts->stretch()) {
799             //
800             // the measure duration does not change,
801             // so its ok to just update the time signatures
802             //
803             TimeSig* nts = staff(staffIdx)->nextTimeSig(tick + Fraction::fromTicks(1));
804             const Fraction lmTick = nts ? nts->segment()->tick() : Fraction(-1, 1);
805             for (Score* score : scoreList()) {
806                   Measure* mf = score->tick2measure(tick);
807                   Measure* lm = (lmTick != Fraction(-1, 1)) ? score->tick2measure(lmTick) : nullptr;
808                   for (Measure* m = mf; m != lm; m = m->nextMeasure()) {
809                         bool changeActual = m->ticks() == m->timesig();
810                         m->undoChangeProperty(Pid::TIMESIG_NOMINAL, QVariant::fromValue(ns));
811                         if (changeActual)
812                               m->undoChangeProperty(Pid::TIMESIG_ACTUAL, QVariant::fromValue(ns));
813                         }
814                   std::pair<int, int> staffIdxRange = getStaffIdxRange(score);
815                   for (int si = staffIdxRange.first; si < staffIdxRange.second; ++si) {
816                         TimeSig* nsig = toTimeSig(seg->element(si * VOICES));
817                         if (!nsig)
818                               continue;
819                         nsig->undoChangeProperty(Pid::SHOW_COURTESY, ts->showCourtesySig());
820                         nsig->undoChangeProperty(Pid::TIMESIG, QVariant::fromValue(ts->sig()));
821                         nsig->undoChangeProperty(Pid::TIMESIG_TYPE, int(ts->timeSigType()));
822                         nsig->undoChangeProperty(Pid::NUMERATOR_STRING, ts->numeratorString());
823                         nsig->undoChangeProperty(Pid::DENOMINATOR_STRING, ts->denominatorString());
824                         nsig->undoChangeProperty(Pid::TIMESIG_STRETCH, QVariant::fromValue(ts->stretch()));
825                         nsig->undoChangeProperty(Pid::GROUPS, QVariant::fromValue(ts->groups()));
826                         nsig->setSelected(false);
827                         nsig->setDropTarget(0);
828                         }
829                   }
830             }
831       else {
832             Score* mScore = masterScore();
833             Measure* mf  = mScore->tick2measure(tick);
834 
835             //
836             // rewrite all measures up to the next time signature
837             //
838             if (mf == mScore->firstMeasure() && mf->nextMeasure() && (mf->ticks() != mf->timesig())) {
839                   // handle upbeat
840                   mf->undoChangeProperty(Pid::TIMESIG_NOMINAL, QVariant::fromValue(ns));
841                   Measure* m = mf->nextMeasure();
842                   Segment* s = m->findSegment(SegmentType::TimeSig, m->tick());
843                   mf = s ? 0 : mf->nextMeasure();
844                   }
845             else {
846                   if (sigmap()->timesig(seg->tick().ticks()).nominal().identical(ns)) {
847                         // no change to global time signature,
848                         // but we need to rewrite any staves with local time signatures
849                         for (int i = 0; i < nstaves(); ++i) {
850                               if (staff(i)->timeSig(tick) && staff(i)->timeSig(tick)->isLocal()) {
851                                     if (!mScore->rewriteMeasures(mf, ns, i)) {
852                                           undoStack()->current()->unwind();
853                                           return;
854                                           }
855                                     }
856                               }
857                         mf = 0;
858                         }
859                   }
860 
861             // try to rewrite the measures first
862             // we will only add time signatures if this succeeds
863             // this means, however, that the rewrite cannot depend on the time signatures being in place
864             if (mf) {
865                   if (!mScore->rewriteMeasures(mf, ns, local ? staffIdx : -1)) {
866                         undoStack()->current()->unwind();
867                         return;
868                         }
869                   }
870             // add the time signatures
871             std::map<int, TimeSig*> masterTimeSigs;
872             for (Score* score : scoreList()) {
873                   Measure* nfm = score->tick2measure(tick);
874                   seg = nfm->undoGetSegment(SegmentType::TimeSig, nfm->tick());
875                   std::pair<int, int> staffIdxRange = getStaffIdxRange(score);
876                   for (int si = staffIdxRange.first; si < staffIdxRange.second; ++si) {
877                         TimeSig* nsig = toTimeSig(seg->element(si * VOICES));
878                         if (nsig == 0) {
879                               nsig = new TimeSig(*ts);
880                               nsig->setScore(score);
881                               nsig->setTrack(si * VOICES);
882                               nsig->setParent(seg);
883                               undoAddElement(nsig);
884                               if (score->excerpt()) {
885                                     const int masterTrack = score->excerpt()->tracks().key(nsig->track());
886                                     TimeSig* masterTimeSig = masterTimeSigs[masterTrack];
887                                     if (masterTimeSig)
888                                           undo(new Link(masterTimeSig, nsig));
889                                     }
890                               }
891                         else {
892                               nsig->undoChangeProperty(Pid::SHOW_COURTESY, ts->showCourtesySig());
893                               nsig->undoChangeProperty(Pid::TIMESIG_TYPE, int(ts->timeSigType()));
894                               nsig->undoChangeProperty(Pid::TIMESIG, QVariant::fromValue(ts->sig()));
895                               nsig->undoChangeProperty(Pid::NUMERATOR_STRING, ts->numeratorString());
896                               nsig->undoChangeProperty(Pid::DENOMINATOR_STRING, ts->denominatorString());
897 
898                               // HACK do it twice to accommodate undo
899                               nsig->undoChangeProperty(Pid::TIMESIG_TYPE, int(ts->timeSigType()));
900                               nsig->undoChangeProperty(Pid::TIMESIG_STRETCH, QVariant::fromValue(ts->stretch()));
901                               nsig->undoChangeProperty(Pid::GROUPS,  QVariant::fromValue(ts->groups()));
902                               nsig->setSelected(false);
903                               nsig->setDropTarget(0);       // DEBUG
904                               }
905 
906                         if (score->isMaster())
907                               masterTimeSigs[nsig->track()] = nsig;
908                         }
909                   }
910             }
911       delete ts;
912       }
913 
914 //---------------------------------------------------------
915 //   cmdRemoveTimeSig
916 //---------------------------------------------------------
917 
cmdRemoveTimeSig(TimeSig * ts)918 void Score::cmdRemoveTimeSig(TimeSig* ts)
919       {
920       if (ts->isLocal() && excerpts().size() > 0) {
921             MScore::setError(CANNOT_CHANGE_LOCAL_TIMESIG);
922             return;
923             }
924 
925       Measure* m = ts->measure();
926       Segment* s = ts->segment();
927 
928       //
929       // we cannot remove a courtesy time signature
930       //
931       if (m->tick() != s->tick())
932             return;
933       Fraction tick = m->tick();
934 
935       // if we remove all time sigs from segment, segment will be already removed by now
936       // but this would leave us no means of detecting that we have have measures in a local timesig
937       // in cases where we try deleting the local time sig
938       // known bug: this means we do not correctly detect non-empty measures when deleting global timesig change after a local one
939       // see http://musescore.org/en/node/51596
940       // Delete the time sig segment from the root score, we will rewriteMeasures from it
941       // since it contains all the music while the part doesn't
942       Score* rScore = masterScore();
943       Measure* rm = rScore->tick2measure(m->tick());
944       Segment* rs = rm->findSegment(SegmentType::TimeSig, s->tick());
945       if (rs)
946             rScore->undoRemoveElement(rs);
947 
948       Measure* pm = m->prevMeasure();
949       Fraction ns(pm ? pm->timesig() : Fraction(4,4));
950 
951       if (!rScore->rewriteMeasures(rm, ns, -1)) {
952             undoStack()->current()->unwind();
953             }
954       else {
955             m = tick2measure(tick);       // old m may have been replaced
956             // hack: fix measure rest durations for staves with local time signatures
957             // if a time signature was deleted to reveal a previous local one,
958             // then rewriteMeasures() got the measure rest durations wrong
959             // (if we fixed it to work for delete, it would fail for add)
960             // so we will fix measure rest durations here
961             // TODO: fix rewriteMeasures() to get this right
962             for (int i = 0; i < nstaves(); ++i) {
963                   TimeSig* tsig = staff(i)->timeSig(tick);
964                   if (tsig && tsig->isLocal()) {
965                         for (Measure* nm = m; nm; nm = nm->nextMeasure()) {
966                               // stop when time signature changes
967                               if (staff(i)->timeSig(nm->tick()) != tsig)
968                                     break;
969                               // fix measure rest duration
970                               ChordRest* cr = nm->findChordRest(nm->tick(), i * VOICES);
971                               if (cr && cr->isRest() && cr->durationType() == TDuration::DurationType::V_MEASURE)
972                                     cr->undoChangeProperty(Pid::DURATION, QVariant::fromValue(nm->stretchedLen(staff(i))));
973                                     //cr->setTicks(nm->stretchedLen(staff(i)));
974                               }
975                         }
976                   }
977             }
978       }
979 
980 //---------------------------------------------------------
981 //  addTiedMidiPitch
982 //---------------------------------------------------------
983 
addTiedMidiPitch(int pitch,bool addFlag,Chord * prevChord)984 Note* Score::addTiedMidiPitch(int pitch, bool addFlag, Chord* prevChord)
985       {
986       Note* n = addMidiPitch(pitch, addFlag);
987       if (prevChord) {
988             Note* nn = prevChord->findNote(n->pitch());
989             if (nn) {
990                   Tie* tie = new Tie(this);
991                   tie->setStartNote(nn);
992                   tie->setEndNote(n);
993                   tie->setTick(tie->startNote()->tick());
994                   tie->setTick2(tie->endNote()->tick());
995                   tie->setTrack(n->track());
996                   n->setTieBack(tie);
997                   nn->setTieFor(tie);
998                   undoAddElement(tie);
999                   }
1000             }
1001       return n;
1002       }
1003 
1004 //---------------------------------------------------------
1005 //  addMidiPitch
1006 //---------------------------------------------------------
1007 
addMidiPitch(int pitch,bool addFlag)1008 Note* Score::addMidiPitch(int pitch, bool addFlag)
1009       {
1010       NoteVal nval(pitch);
1011       Staff* st = staff(inputState().track() / VOICES);
1012 
1013       // if transposing, interpret MIDI pitch as representing desired written pitch
1014       // set pitch based on corresponding sounding pitch
1015       if (!styleB(Sid::concertPitch))
1016             nval.pitch += st->part()->instrument(inputState().tick())->transpose().chromatic;
1017       // let addPitch calculate tpc values from pitch
1018       //Key key   = st->key(inputState().tick());
1019       //nval.tpc1 = pitch2tpc(nval.pitch, key, Prefer::NEAREST);
1020       return addPitch(nval, addFlag);
1021       }
1022 
1023 //---------------------------------------------------------
1024 //   searchNote
1025 //    search for note or rest before or at tick position tick
1026 //    in staff
1027 //---------------------------------------------------------
1028 
searchNote(const Fraction & tick,int track) const1029 ChordRest* Score::searchNote(const Fraction& tick, int track) const
1030       {
1031       ChordRest* ipe = 0;
1032       SegmentType st = SegmentType::ChordRest;
1033       for (Segment* segment = firstSegment(st); segment; segment = segment->next1(st)) {
1034             ChordRest* cr = segment->cr(track);
1035             if (!cr)
1036                   continue;
1037             if (cr->tick() == tick)
1038                   return cr;
1039             if (cr->tick() >  tick)
1040                   return ipe ? ipe : cr;
1041             ipe = cr;
1042             }
1043       return 0;
1044       }
1045 
1046 //---------------------------------------------------------
1047 //   regroupNotesAndRests
1048 //    * combine consecutive rests into fewer rests of longer duration.
1049 //    * combine tied notes/chords into fewer notes of longer duration.
1050 //    Only operates on one voice - protects manual layout adjustment, etc.
1051 //---------------------------------------------------------
1052 
regroupNotesAndRests(const Fraction & startTick,const Fraction & endTick,int track)1053 void Score::regroupNotesAndRests(const Fraction& startTick, const Fraction& endTick, int track)
1054       {
1055       Segment* inputSegment = _is.segment(); // store this so we can get back to it later.
1056       Segment* seg = tick2segment(startTick, true, SegmentType::ChordRest);
1057       for (Measure* msr = seg->measure(); msr && msr->tick() < endTick; msr = msr->nextMeasure()) {
1058             Fraction maxTick = endTick > msr->endTick() ? msr->endTick() : endTick;
1059             if (!seg || seg->measure() != msr)
1060                   seg = msr->first(SegmentType::ChordRest);
1061             for (; seg; seg = seg->next(SegmentType::ChordRest)) {
1062                   ChordRest* curr = seg->cr(track);
1063                   if (!curr)
1064                         continue; // this voice is empty here (CR overlaps with CR in other track)
1065                   if (seg->tick() + curr->actualTicks() > maxTick)
1066                         break; // outside range
1067                   if (curr->isRest() && !(curr->tuplet()) && !(toRest(curr)->isGap())) {
1068                         // combine consecutive rests
1069                         ChordRest* lastRest = curr;
1070                         for (Segment* s = seg->next(SegmentType::ChordRest); s; s = s->next(SegmentType::ChordRest)) {
1071                               ChordRest* cr = s->cr(track);
1072                               if (!cr)
1073                                     continue; // this voice is empty here
1074                               if (!cr->isRest() || s->tick() + cr->actualTicks() > maxTick || toRest(cr)->isGap())
1075                                     break; // next element in the same voice is not a rest, or it exceeds the selection, or it is a gap
1076                               lastRest = cr;
1077                               }
1078                         Fraction restTicks = lastRest->tick() + lastRest->ticks() - curr->tick();
1079                         seg = setNoteRest(seg, curr->track(), NoteVal(), restTicks, Direction::AUTO, false, true);
1080                         }
1081                   else if (curr->isChord()) {
1082                         // combine tied chords
1083                         Chord* chord = toChord(curr);
1084                         Chord* lastTiedChord = chord;
1085                         for (Chord* next = chord->nextTiedChord(); next && next->tick() + next->ticks() <= maxTick; next = next->nextTiedChord()) {
1086                               lastTiedChord = next;
1087                               }
1088                         if (!lastTiedChord)
1089                               lastTiedChord = chord;
1090                         Fraction noteTicks = lastTiedChord->tick() + lastTiedChord->ticks() - chord->tick();
1091                         if (!(curr->tuplet())) {
1092                               // store start/end note for backward/forward ties ending/starting on the group of notes being rewritten
1093                               size_t numNotes = chord->notes().size();
1094 #if (!defined (_MSCVER) && !defined (_MSC_VER))
1095                               Note* tieBack[numNotes];
1096                               Note* tieFor[numNotes];
1097 #else
1098                               // MSVC does not support VLA. Replace with std::vector. If profiling determines that the
1099                               //    heap allocation is slow, an optimization might be used.
1100                               std::vector<Note *> tieBack(numNotes);
1101                               std::vector<Note *> tieFor(numNotes);
1102 #endif
1103                               for (size_t i = 0; i < numNotes; i++) {
1104                                     Note* n = chord->notes()[i];
1105                                     Note* nn = lastTiedChord->notes()[i];
1106                                     if (n->tieBack())
1107                                           tieBack[i] = n->tieBack()->startNote();
1108                                     else
1109                                           tieBack[i] = 0;
1110                                     if (nn->tieFor())
1111                                           tieFor[i] = nn->tieFor()->endNote();
1112                                     else
1113                                           tieFor[i] = 0;
1114                                     }
1115                               Fraction tick = seg->tick();
1116                               int tr        = chord->track();
1117                               Fraction sd   = noteTicks;
1118                               Tie* tie      = 0;
1119                               Segment* segment = seg;
1120                               ChordRest* cr = toChordRest(segment->element(tr));
1121                               Chord* nchord = toChord(chord->clone());
1122                               for (size_t i = 0; i < numNotes; i++) { // strip ties from cloned chord
1123                                     Note* n = nchord->notes()[i];
1124                                     n->setTieFor(0);
1125                                     n->setTieBack(0);
1126                                     }
1127                               Chord* startChord = nchord;
1128                               Measure* measure = 0;
1129                               bool firstpart = true;
1130                               for (;;) {
1131                                     if (tr % VOICES)
1132                                           expandVoice(segment, tr);
1133                                     // the returned gap ends at the measure boundary or at tuplet end
1134                                     Fraction dd = makeGap(segment, tr, sd, cr->tuplet());
1135                                     if (dd.isZero())
1136                                           break;
1137                                     measure = segment->measure();
1138                                     std::vector<TDuration> dl;
1139                                     dl = toRhythmicDurationList(dd, false, segment->rtick(), sigmap()->timesig(tick.ticks()).nominal(), measure, 1);
1140                                     size_t n = dl.size();
1141                                     for (size_t i = 0; i < n; ++i) {
1142                                           const TDuration& d = dl[i];
1143                                           Chord* nchord2 = toChord(nchord->clone());
1144                                           if (!firstpart)
1145                                                 nchord2->removeMarkings(true);
1146                                           nchord2->setDurationType(d);
1147                                           nchord2->setTicks(d.fraction());
1148                                           std::vector<Note*> nl1 = nchord->notes();
1149                                           std::vector<Note*> nl2 = nchord2->notes();
1150                                           if (!firstpart)
1151                                                 for (size_t j = 0; j < nl1.size(); ++j) {
1152                                                       tie = new Tie(this);
1153                                                       tie->setStartNote(nl1[j]);
1154                                                       tie->setEndNote(nl2[j]);
1155                                                       tie->setTick(tie->startNote()->tick());
1156                                                       tie->setTick2(tie->endNote()->tick());
1157                                                       tie->setTrack(tr);
1158                                                       nl1[j]->setTieFor(tie);
1159                                                       nl2[j]->setTieBack(tie);
1160                                                       }
1161                                           undoAddCR(nchord2, measure, tick);
1162                                           segment = nchord2->segment();
1163                                           tick += nchord2->actualTicks();
1164                                           nchord = nchord2;
1165                                           firstpart = false;
1166                                           }
1167                                     sd -= dd;
1168                                     if (sd.isZero())
1169                                           break;
1170                                     Segment* nseg = tick2segment(tick, false, SegmentType::ChordRest);
1171                                     if (nseg == 0)
1172                                           break;
1173                                     segment = nseg;
1174                                     cr = toChordRest(segment->element(tr));
1175                                     if (cr == 0) {
1176                                           if (tr % VOICES)
1177                                                 cr = addRest(segment, tr, TDuration(TDuration::DurationType::V_MEASURE), 0);
1178                                           else
1179                                                 break;
1180                                           }
1181                                     }
1182                               if (_is.slur()) {
1183                                     // extend slur
1184                                     _is.slur()->undoChangeProperty(Pid::SPANNER_TICKS, nchord->tick() - _is.slur()->tick());
1185                                     for (ScoreElement* e : _is.slur()->linkList()) {
1186                                           Slur* slur = toSlur(e);
1187                                           for (ScoreElement* ee : nchord->linkList()) {
1188                                                 Element* e1 = static_cast<Element*>(ee);
1189                                                 if (e1->score() == slur->score() && e1->track() == slur->track2()) {
1190                                                       slur->score()->undo(new ChangeSpannerElements(slur, slur->startElement(), e1));
1191                                                       break;
1192                                                       }
1193                                                 }
1194                                           }
1195                                     }
1196                               // recreate previously stored pending ties
1197                               for (size_t i = 0; i < numNotes; i++) {
1198                                     Note* n = startChord->notes()[i];
1199                                     Note* nn = nchord->notes()[i];
1200                                     if (tieBack[i]) {
1201                                           tie = new Tie(this);
1202                                           tie->setStartNote(tieBack[i]);
1203                                           tie->setEndNote(n);
1204                                           tie->setTick(tie->startNote()->tick());
1205                                           tie->setTick2(tie->endNote()->tick());
1206                                           tie->setTrack(track);
1207                                           n->setTieBack(tie);
1208                                           tieBack[i]->setTieFor(tie);
1209                                           undoAddElement(tie);
1210                                           }
1211                                     if (tieFor[i]) {
1212                                           tie = new Tie(this);
1213                                           tie->setStartNote(nn);
1214                                           tie->setEndNote(tieFor[i]);
1215                                           tie->setTick(tie->startNote()->tick());
1216                                           tie->setTick2(tie->endNote()->tick());
1217                                           tie->setTrack(track);
1218                                           n->setTieFor(tie);
1219                                           tieFor[i]->setTieBack(tie);
1220                                           undoAddElement(tie);
1221                                           }
1222                                     }
1223                               if (tie) // at least one tie was created
1224                                     connectTies();
1225                               }
1226                         }
1227                   }
1228             }
1229       // now put the input state back where it was before
1230       _is.setSegment(inputSegment);
1231       }
1232 
1233 //---------------------------------------------------------
1234 //   cmdTieNoteList
1235 //---------------------------------------------------------
1236 
cmdTieNoteList(const Selection & selection,bool noteEntryMode)1237 std::vector<Note*> Score::cmdTieNoteList(const Selection& selection, bool noteEntryMode)
1238       {
1239       Element* el = selection.element();
1240       if (Note* n = InputState::note(el)) {
1241             if (noteEntryMode)
1242                   return n->chord()->notes();
1243             else
1244                   return { n };
1245             }
1246       else {
1247             ChordRest* cr = InputState::chordRest(el);
1248             if (cr && cr->isChord())
1249                   return toChord(cr)->notes();
1250             }
1251       return selection.noteList();
1252       }
1253 
1254 //---------------------------------------------------------
1255 //   cmdAddTie
1256 //---------------------------------------------------------
1257 
cmdAddTie(bool addToChord)1258 void Score::cmdAddTie(bool addToChord)
1259       {
1260       const std::vector<Note*> noteList = cmdTieNoteList(selection(), noteEntryMode());
1261 
1262       if (noteList.empty()) {
1263             qDebug("no notes selected");
1264             return;
1265             }
1266 
1267       startCmd();
1268       Chord* lastAddedChord = 0;
1269       for (Note* note : noteList) {
1270             if (note->tieFor()) {
1271                   qDebug("cmdAddTie: note %p has already tie? noteFor: %p", note, note->tieFor());
1272                   continue;
1273                   }
1274 
1275             if (noteEntryMode()) {
1276                   ChordRest* cr = nullptr;
1277                   Chord* c = note->chord();
1278 
1279                   // set cursor at position after note
1280                   if (c->isGraceBefore()) {
1281                         // tie grace note before to main note
1282                         cr = toChord(c->parent());
1283                         addToChord = true;
1284                         }
1285                   else {
1286                         _is.setSegment(note->chord()->segment());
1287                         _is.moveToNextInputPos();
1288                         _is.setLastSegment(_is.segment());
1289 
1290                         if (_is.cr() == 0)
1291                               expandVoice();
1292                         cr = _is.cr();
1293                         }
1294                   if (cr == 0)
1295                         break;
1296 
1297                   bool addFlag = lastAddedChord != nullptr;
1298 
1299                   // try to re-use existing note or chord
1300                   Note* n = nullptr;
1301                   if (addToChord && cr->isChord()) {
1302                         Chord* chord = toChord(cr);
1303                         Note* nn = chord->findNote(note->pitch());
1304                         if (nn && nn->tpc() == note->tpc())
1305                               n = nn;           // re-use note
1306                         else
1307                               addFlag = true;   // re-use chord
1308                         }
1309 
1310                   // if no note to re-use, create one
1311                   NoteVal nval(note->noteVal());
1312                   if (!n)
1313                         n = addPitch(nval, addFlag);
1314                   else
1315                         select(n);
1316 
1317                   if (n) {
1318                         if (!lastAddedChord)
1319                               lastAddedChord = n->chord();
1320                         // n is not necessarily next note if duration span over measure
1321                         Note* nnote = searchTieNote(note);
1322                         while (nnote) {
1323                               // DEBUG: if duration spans over measure
1324                               // this does not set line for intermediate notes
1325                               // tpc was set correctly already
1326                               //n->setLine(note->line());
1327                               //n->setTpc(note->tpc());
1328                               Tie* tie = new Tie(this);
1329                               tie->setStartNote(note);
1330                               tie->setEndNote(nnote);
1331                               tie->setTrack(note->track());
1332                               tie->setTick(note->chord()->segment()->tick());
1333                               tie->setTicks(nnote->chord()->segment()->tick() - note->chord()->segment()->tick());
1334                               undoAddElement(tie);
1335                               if (!addFlag || nnote->chord()->tick() >= lastAddedChord->tick() || nnote->chord()->isGrace()) {
1336                                     break;
1337                                     }
1338                               else {
1339                                     note = nnote;
1340                                     _is.setLastSegment(_is.segment());
1341                                     nnote = addPitch(nval, true);
1342                                     }
1343                               }
1344                         }
1345                   }
1346             else {
1347                   Note* note2 = searchTieNote(note);
1348                   if (note2) {
1349                         Tie* tie = new Tie(this);
1350                         tie->setStartNote(note);
1351                         tie->setEndNote(note2);
1352                         tie->setTrack(note->track());
1353                         tie->setTick(note->chord()->segment()->tick());
1354                         tie->setTicks(note2->chord()->segment()->tick() - note->chord()->segment()->tick());
1355                         undoAddElement(tie);
1356                         }
1357                   }
1358             }
1359       if (lastAddedChord)
1360             nextInputPos(lastAddedChord, false);
1361       endCmd();
1362       }
1363 
1364 //---------------------------------------------------------
1365 //   cmdRemoveTie
1366 //---------------------------------------------------------
1367 
cmdToggleTie()1368 void Score::cmdToggleTie()
1369       {
1370       const std::vector<Note*> noteList = cmdTieNoteList(selection(), noteEntryMode());
1371 
1372       if (noteList.empty()) {
1373             qDebug("no notes selected");
1374             return;
1375             }
1376 
1377       bool canAddTies = false;
1378       const size_t notes = noteList.size();
1379       std::vector<Note*> tieNoteList(notes);
1380 
1381       for (size_t i = 0; i < notes; ++i) {
1382             Note* n = noteList[i];
1383             if (n->tieFor()) {
1384                   tieNoteList[i] = nullptr;
1385                   }
1386             else {
1387                   Note* tieNote = searchTieNote(n);
1388                   tieNoteList[i] = tieNote;
1389                   if (tieNote)
1390                         canAddTies = true;
1391                   }
1392             }
1393 
1394       startCmd();
1395 
1396       if (canAddTies) {
1397             for (size_t i = 0; i < notes; ++i) {
1398                   Note* note2 = tieNoteList[i];
1399                   if (note2) {
1400                         Note* note = noteList[i];
1401 
1402                         Tie* tie = new Tie(this);
1403                         tie->setStartNote(note);
1404                         tie->setEndNote(note2);
1405                         tie->setTrack(note->track());
1406                         tie->setTick(note->chord()->segment()->tick());
1407                         tie->setTicks(note2->chord()->segment()->tick() - note->chord()->segment()->tick());
1408                         undoAddElement(tie);
1409                         }
1410                   }
1411             }
1412       else {
1413             for (Note* n : noteList) {
1414                   Tie* tie = n->tieFor();
1415                   if (tie)
1416                         undoRemoveElement(tie);
1417                   }
1418             }
1419 
1420       endCmd();
1421       }
1422 
1423 
1424 //---------------------------------------------------------
1425 //   cmdAddOttava
1426 //---------------------------------------------------------
1427 
cmdAddOttava(OttavaType type)1428 void Score::cmdAddOttava(OttavaType type)
1429       {
1430       const Selection sel = selection(); // copy selection state before the operation.
1431       // add on each staff if possible
1432       if (sel.isRange() && sel.staffStart() != sel.staffEnd() - 1) {
1433             for (int staffIdx = sel.staffStart() ; staffIdx < sel.staffEnd(); ++staffIdx) {
1434                   ChordRest* cr1 = sel.firstChordRest(staffIdx * VOICES);
1435                   ChordRest* cr2 = sel.lastChordRest(staffIdx * VOICES);
1436                   if (!cr1)
1437                        continue;
1438                   if (cr2 == 0)
1439                        cr2 = cr1;
1440                   Ottava* ottava = new Ottava(this);
1441                   ottava->setOttavaType(type);
1442                   ottava->setTrack(cr1->track());
1443                   ottava->setTrack2(cr1->track());
1444                   ottava->setTick(cr1->tick());
1445                   ottava->setTick2(cr2->tick() + cr2->actualTicks());
1446                   undoAddElement(ottava);
1447                   }
1448             }
1449       else {
1450             ChordRest* cr1;
1451             ChordRest* cr2;
1452             getSelectedChordRest2(&cr1, &cr2);
1453             if (!cr1)
1454                   return;
1455             if (cr2 == 0)
1456                   cr2 = cr1;
1457 
1458             Ottava* ottava = new Ottava(this);
1459             ottava->setOttavaType(type);
1460 
1461             ottava->setTrack(cr1->track());
1462             ottava->setTrack2(cr1->track());
1463             ottava->setTick(cr1->tick());
1464             ottava->setTick2(cr2->tick() + cr2->actualTicks());
1465             undoAddElement(ottava);
1466             if (!noteEntryMode())
1467                   select(ottava, SelectType::SINGLE, 0);
1468             }
1469       }
1470 
1471 //---------------------------------------------------------
1472 //   cmdSetBeamMode
1473 //---------------------------------------------------------
1474 
cmdSetBeamMode(Beam::Mode mode)1475 void Score::cmdSetBeamMode(Beam::Mode mode)
1476       {
1477       for (ChordRest* cr : getSelectedChordRests()) {
1478             if (cr)
1479                   cr->undoChangeProperty(Pid::BEAM_MODE, int(mode));
1480             }
1481       }
1482 
1483 //---------------------------------------------------------
1484 //   cmdFlip
1485 //---------------------------------------------------------
1486 
cmdFlip()1487 void Score::cmdFlip()
1488       {
1489       const QList<Element*>& el = selection().elements();
1490       if (el.empty()) {
1491             MScore::setError(NO_FLIPPABLE_SELECTED);
1492             return;
1493             }
1494 
1495       std::set<const Element*> alreadyFlippedElements;
1496       auto flipOnce = [&alreadyFlippedElements](const Element* element, std::function<void()> flipFunction) -> void {
1497             if (alreadyFlippedElements.count(element) == 0) {
1498                   alreadyFlippedElements.insert(element);
1499                   flipFunction();
1500                   }
1501             };
1502       for (Element* e : el) {
1503             if (e->isNote() || e->isStem() || e->isHook()) {
1504                   Chord* chord = nullptr;
1505                   if (e->isNote()) {
1506                         auto note = toNote(e);
1507                         chord = note->chord();
1508                         }
1509                   else if (e->isStem())
1510                         chord = toStem(e)->chord();
1511                   else
1512                         chord = toHook(e)->chord();
1513 
1514                   if (chord->beam()) {
1515                         if (!selection().isRange())
1516                               e = chord->beam();
1517                         else
1518                               continue;
1519                         }
1520                   else {
1521                         flipOnce(chord, [chord](){
1522                               Direction dir = chord->up() ? Direction::DOWN : Direction::UP;
1523                               chord->undoChangeProperty(Pid::STEM_DIRECTION, QVariant::fromValue<Direction>(dir));
1524                               });
1525                         }
1526                   }
1527 
1528             if (e->isBeam()) {
1529                   auto beam = toBeam(e);
1530                   flipOnce(beam, [beam](){
1531                         Direction dir = beam->up() ? Direction::DOWN : Direction::UP;
1532                         beam->undoChangeProperty(Pid::STEM_DIRECTION, QVariant::fromValue<Direction>(dir));
1533                         });
1534                   }
1535             else if (e->isSlurTieSegment()) {
1536                   auto slurTieSegment = toSlurTieSegment(e)->slurTie();
1537                   flipOnce(slurTieSegment, [slurTieSegment](){
1538                         Direction dir = slurTieSegment->up() ? Direction::DOWN : Direction::UP;
1539                         slurTieSegment->undoChangeProperty(Pid::SLUR_DIRECTION, QVariant::fromValue<Direction>(dir));
1540                         });
1541                   }
1542             else if (e->isArticulation()) {
1543                   auto articulation = toArticulation(e);
1544                   flipOnce(articulation, [articulation](){
1545                         ArticulationAnchor articAnchor = articulation->anchor();
1546                         switch (articAnchor) {
1547                               case ArticulationAnchor::TOP_CHORD:
1548                                     articAnchor = ArticulationAnchor::BOTTOM_CHORD;
1549                                     break;
1550                               case ArticulationAnchor::BOTTOM_CHORD:
1551                                     articAnchor = ArticulationAnchor::TOP_CHORD;
1552                                     break;
1553                               case ArticulationAnchor::CHORD:
1554                                     articAnchor = articulation->up() ? ArticulationAnchor::BOTTOM_CHORD : ArticulationAnchor::TOP_CHORD;
1555                                     break;
1556                               case ArticulationAnchor::TOP_STAFF:
1557                                     articAnchor = ArticulationAnchor::BOTTOM_STAFF;
1558                                     break;
1559                               case ArticulationAnchor::BOTTOM_STAFF:
1560                                     articAnchor = ArticulationAnchor::TOP_STAFF;
1561                                     break;
1562                               }
1563                         PropertyFlags pf = articulation->propertyFlags(Pid::ARTICULATION_ANCHOR);
1564                         if (pf == PropertyFlags::STYLED)
1565                                 pf = PropertyFlags::UNSTYLED;
1566                         articulation->undoChangeProperty(Pid::ARTICULATION_ANCHOR, int(articAnchor), pf);
1567                         });
1568                   }
1569             else if (e->isTuplet()) {
1570                   auto tuplet = toTuplet(e);
1571                   flipOnce(tuplet, [tuplet](){
1572                         Direction dir = tuplet->isUp() ? Direction::DOWN : Direction::UP;
1573                         tuplet->undoChangeProperty(Pid::DIRECTION, QVariant::fromValue<Direction>(dir), PropertyFlags::UNSTYLED);
1574                         });
1575                   }
1576             else if (e->isNoteDot() && e->parent()->isNote()) {
1577                   Note* note = toNote(e->parent());
1578                   Direction d = note->dotIsUp() ? Direction::DOWN : Direction::UP;
1579                   note->undoChangeProperty(Pid::DOT_POSITION, QVariant::fromValue<Direction>(d));
1580                   }
1581             else if (e->isTempoText()
1582                || e->isSystemText()
1583                || e->isJump()
1584                || e->isMarker()
1585                || e->isStaffText()
1586                || e->isSticking()
1587                || e->isFingering()
1588                || e->isDynamic()
1589                || e->isHarmony()
1590                || e->isInstrumentChange()
1591                || e->isRehearsalMark()
1592                || e->isMeasureNumber()
1593                || e->isFretDiagram()
1594                || e->isHairpin()
1595                || e->isHairpinSegment()
1596                || e->isOttavaSegment()
1597                || e->isTextLineSegment()
1598                || e->isPedalSegment()
1599                || e->isLetRingSegment()
1600                || e->isPalmMuteSegment()
1601                || e->isFermata()
1602                || e->isLyrics()
1603                || e->isTrillSegment()
1604                || e->isBreath()) {
1605                   e->undoChangeProperty(Pid::AUTOPLACE, true);
1606                   // getProperty() delegates call from spannerSegment to Spanner
1607                   Placement p = Placement(e->getProperty(Pid::PLACEMENT).toInt());
1608                   p = (p == Placement::ABOVE) ? Placement::BELOW : Placement::ABOVE;
1609                   // TODO: undoChangeProperty() should probably do this directly
1610                   // see https://musescore.org/en/node/281432
1611                   Element* ee = e->propertyDelegate(Pid::PLACEMENT);
1612                   if (!ee)
1613                         ee = e;
1614                   PropertyFlags pf = ee->propertyFlags(Pid::PLACEMENT);
1615                   if (pf == PropertyFlags::STYLED)
1616                         pf = PropertyFlags::UNSTYLED;
1617                   qreal oldDefaultY = ee->propertyDefault(Pid::OFFSET).toPointF().y();
1618                   ee->undoChangeProperty(Pid::PLACEMENT, int(p), pf);
1619                   // flip and rebase user offset to new default now that placement has changed
1620                   qreal newDefaultY = ee->propertyDefault(Pid::OFFSET).toPointF().y();
1621                   if (ee->isSpanner()) {
1622                         Spanner* spanner = toSpanner(ee);
1623                         for (SpannerSegment* ss : spanner->spannerSegments()) {
1624                               if (!ss->isStyled(Pid::OFFSET)) {
1625                                     QPointF off = ss->getProperty(Pid::OFFSET).toPointF();
1626                                     qreal oldY = off.y() - oldDefaultY;
1627                                     off.ry() = newDefaultY - oldY;
1628                                     ss->undoChangeProperty(Pid::OFFSET, off);
1629                                     ss->setOffsetChanged(false);
1630                                     }
1631                               }
1632                         }
1633                   else if (!ee->isStyled(Pid::OFFSET)) {
1634                         QPointF off = ee->getProperty(Pid::OFFSET).toPointF();
1635                         qreal oldY = off.y() - oldDefaultY;
1636                         off.ry() = newDefaultY - oldY;
1637                         ee->undoChangeProperty(Pid::OFFSET, off);
1638                         ee->setOffsetChanged(false);
1639                         }
1640                   }
1641             }
1642       }
1643 
1644 //---------------------------------------------------------
1645 //   deleteItem
1646 //---------------------------------------------------------
1647 
deleteItem(Element * el)1648 void Score::deleteItem(Element* el)
1649       {
1650       if (!el)
1651             return;
1652       // cannot remove generated elements
1653       if (el->generated() && !(el->isBracket() || el->isBarLine() || el->isClef() || el->isMeasureNumber()))
1654             return;
1655 //      qDebug("%s", el->name());
1656 
1657       switch (el->type()) {
1658             case ElementType::INSTRUMENT_NAME: {
1659                   Part* part = el->part();
1660                   InstrumentName* in = toInstrumentName(el);
1661                   if (in->instrumentNameType() == InstrumentNameType::LONG)
1662                         undo(new ChangeInstrumentLong(Fraction(0,1), part, QList<StaffName>()));
1663                   else if (in->instrumentNameType() == InstrumentNameType::SHORT)
1664                         undo(new ChangeInstrumentShort(Fraction(0,1), part, QList<StaffName>()));
1665                   }
1666                   break;
1667 
1668             case ElementType::TIMESIG: {
1669                   // timesig might already be removed
1670                   TimeSig* ts = toTimeSig(el);
1671                   Segment* s = ts->segment();
1672                   Measure* m = s->measure();
1673                   Segment* ns = m->findSegment(s->segmentType(), s->tick());
1674                   if (!ns || (ns->element(ts->track()) != ts)) {
1675                         qDebug("deleteItem: not found");
1676                         break;
1677                         }
1678                   cmdRemoveTimeSig(ts);
1679                   }
1680                   break;
1681 
1682             case ElementType::KEYSIG:
1683                   {
1684                   KeySig* k = toKeySig(el);
1685                   undoRemoveElement(k);
1686                   for (int i = 0; i < k->part()->nstaves(); i++) {
1687                         Staff* staff = k->part()->staff(i);
1688                         KeySigEvent e = staff->keySigEvent(k->tick());
1689                         updateInstrumentChangeTranspositions(e, staff, k->tick());
1690                         }
1691                   }
1692                   break;
1693 
1694             case ElementType::NOTE:
1695                   {
1696                   Chord* chord = toChord(el->parent());
1697                   if (chord->notes().size() > 1) {
1698                         undoRemoveElement(el);
1699                         select(chord->downNote(), SelectType::SINGLE, 0);
1700                         break;
1701                         }
1702                   // else fall through
1703                   el = chord;
1704                   }
1705                   // fall through
1706 
1707             case ElementType::CHORD:
1708                   {
1709                   Chord* chord = toChord(el);
1710                   removeChordRest(chord, false);
1711 
1712                   // replace with rest
1713                   if (chord->noteType() == NoteType::NORMAL) {
1714                         Rest* rest = new Rest(this, chord->durationType());
1715                         rest->setDurationType(chord->durationType());
1716                         rest->setTicks(chord->ticks());
1717 
1718                         rest->setTrack(el->track());
1719                         rest->setParent(chord->parent());
1720 
1721                         Segment* segment = chord->segment();
1722                         undoAddCR(rest, segment->measure(), segment->tick());
1723 
1724                         Tuplet* tuplet = chord->tuplet();
1725                         if (tuplet) {
1726                               QList<ScoreElement*> tl = tuplet->linkList();
1727                               for (ScoreElement* e : rest->linkList()) {
1728                                     DurationElement* de = toDurationElement(e);
1729                                     for (ScoreElement* ee : qAsConst(tl)) {
1730                                           Tuplet* t = toTuplet(ee);
1731                                           if (t->score() == de->score() && t->track() == de->track()) {
1732                                                 de->setTuplet(t);
1733                                                 t->add(de);
1734                                                 break;
1735                                                 }
1736                                           }
1737                                     }
1738                               }
1739                         //select(rest, SelectType::SINGLE, 0);
1740                         }
1741                   else  {
1742                         // remove segment if empty
1743                         Segment* seg = chord->segment();
1744                         if (seg->empty())
1745                               undoRemoveElement(seg);
1746                         }
1747                   }
1748                   break;
1749 
1750             case ElementType::REPEAT_MEASURE:
1751                   {
1752                   RepeatMeasure* rm = toRepeatMeasure(el);
1753                   removeChordRest(rm, false);
1754                   Rest* rest = new Rest(this);
1755                   rest->setDurationType(TDuration::DurationType::V_MEASURE);
1756                   rest->setTicks(rm->measure()->stretchedLen(rm->staff()));
1757                   rest->setTrack(rm->track());
1758                   rest->setParent(rm->parent());
1759                   Segment* segment = rm->segment();
1760                   undoAddCR(rest, segment->measure(), segment->tick());
1761                   }
1762                   // fall through
1763 
1764             case ElementType::REST:
1765                   //
1766                   // only allow for voices != 0
1767                   //    e.g. voice 0 rests cannot be removed
1768                   //
1769                   {
1770                   Rest* rest = toRest(el);
1771                   if (rest->tuplet() && rest->tuplet()->elements().empty())
1772                         undoRemoveElement(rest->tuplet());
1773                   if ((el->voice() != 0) && !rest->tuplet()) {
1774                         rest->undoChangeProperty(Pid::GAP, true);
1775                         for (ScoreElement* r : el->linkList()) {
1776                               Rest* rr = toRest(r);
1777                               if (rr->track() % VOICES)
1778                                     rr->undoChangeProperty(Pid::GAP, true);
1779                               }
1780 
1781                         // delete them really when only gap rests are in the actual measure.
1782                         Measure* m = toRest(el)->measure();
1783                         int track = el->track();
1784                         if (m->isOnlyDeletedRests(track)) {
1785                               static const SegmentType st { SegmentType::ChordRest };
1786                               for (const Segment* s = m->first(st); s; s = s->next(st)) {
1787                                     Element* del = s->element(track);
1788                                     if (s->segmentType() != st || !del)
1789                                           continue;
1790                                     if (toRest(del)->isGap())
1791                                           undoRemoveElement(del);
1792                                     }
1793                               checkSpanner(m->tick(), m->endTick());
1794                               }
1795                         else {
1796                               // check if the other rest could be combined
1797                               Segment* s = toRest(el)->segment();
1798 
1799                               std::vector<Rest*> rests;
1800                               // find previous segment with cr in this track
1801                               Element* pe = 0;
1802                               for (Segment* ps = s->prev(SegmentType::ChordRest); ps; ps = ps->prev(SegmentType::ChordRest)) {
1803                                     Element* elm = ps->element(track);
1804                                     if (elm && elm->isRest() && toRest(elm)->isGap()) {
1805                                           pe = el;
1806                                           rests.push_back(toRest(elm));
1807                                           }
1808                                     else if (elm)
1809                                           break;
1810                                     }
1811                               // find next segment with cr in this track
1812                               Segment* ns;
1813                               Element* ne = 0;
1814                               for (ns = s->next(SegmentType::ChordRest); ns; ns = ns->next(SegmentType::ChordRest)) {
1815                                     Element* elm = ns->element(track);
1816                                     if (elm && elm->isRest() && toRest(elm)->isGap()) {
1817                                           ne = elm;
1818                                           rests.push_back(toRest(elm));
1819                                           }
1820                                     else if (elm)
1821                                           break;
1822                                     }
1823 
1824                               Fraction stick = pe ? pe->tick() : s->tick();
1825                               Fraction ticks = { 0, 1 };
1826 
1827                               if (ne)
1828                                     ticks = ne->tick() - stick + toRest(ne)->actualTicks();
1829                               else if (ns)
1830                                     ticks = ns->tick() - stick;
1831                               else
1832                                     ticks = m->ticks() + m->tick() - stick;
1833 
1834                               if (ticks != m->ticks() && ticks != s->ticks()) {
1835                                     undoRemoveElement(rest);
1836                                     for (Rest* r : rests) {
1837                                           undoRemoveElement(r);
1838                                           }
1839 
1840                                     Fraction f = ticks;
1841 
1842                                     std::vector<TDuration> dList = toDurationList(f, true);
1843                                     if (dList.empty())
1844                                           break;
1845 
1846                                     for (const TDuration& d : dList) {
1847                                           Rest* rr = new Rest(this);
1848                                           rr->setTicks(d.fraction());
1849                                           rr->setDurationType(d);
1850                                           rr->setTrack(track);
1851                                           rr->setGap(true);
1852                                           undoAddCR(rr, m, stick);
1853                                           }
1854                                     }
1855                               }
1856                         // Set input position
1857                         // TODO If deleted element is last of a sequence, use prev?
1858                         if (noteEntryMode())
1859                               score()->move("prev-chord");
1860                         }
1861                   }
1862                   break;
1863 
1864             case ElementType::ACCIDENTAL:
1865                   if (el->parent()->isNote())
1866                         changeAccidental(toNote(el->parent()), AccidentalType::NONE);
1867                   else
1868                         undoRemoveElement(el);
1869                   break;
1870 
1871             case ElementType::BAR_LINE: {
1872                   BarLine* bl = toBarLine(el);
1873                   Segment* s = bl->segment();
1874                   Measure* m = s->measure();
1875                   if (s->isBeginBarLineType() || s->isBarLineType()) {
1876                         undoRemoveElement(el);
1877                         }
1878                   else {
1879                         if (bl->barLineType() == BarLineType::START_REPEAT) {
1880                               Measure* m2 = m->isMMRest() ? m->mmRestFirst() : m;
1881                               for (Score* lscore : score()->scoreList()) {
1882                                     Measure* lmeasure = lscore->tick2measure(m2->tick());
1883                                     if (lmeasure)
1884                                           lmeasure->undoChangeProperty(Pid::REPEAT_START, false);
1885                                     }
1886                               }
1887                         else if (bl->barLineType() == BarLineType::END_REPEAT) {
1888                               Measure* m2 = m->isMMRest() ? m->mmRestLast() : m;
1889                               for (Score* lscore : score()->scoreList()) {
1890                                     Measure* lmeasure = lscore->tick2measure(m2->tick());
1891                                     if (lmeasure)
1892                                           lmeasure->undoChangeProperty(Pid::REPEAT_END, false);
1893                                     }
1894                               }
1895                         else {
1896                               bl->undoChangeProperty(Pid::BARLINE_TYPE, QVariant::fromValue(BarLineType::NORMAL));
1897                               }
1898                         }
1899                   }
1900                   break;
1901 
1902             case ElementType::TUPLET:
1903                   cmdDeleteTuplet(toTuplet(el), true);
1904                   break;
1905 
1906             case ElementType::MEASURE: {
1907                   Measure* m = toMeasure(el);
1908                   undoRemoveMeasures(m, m);
1909                   undoInsertTime(m->tick(), -(m->endTick() - m->tick()));
1910                   }
1911                   break;
1912 
1913             case ElementType::BRACKET:
1914                   undoRemoveBracket(toBracket(el));
1915                   break;
1916 
1917             case ElementType::LAYOUT_BREAK:
1918                   {
1919                   undoRemoveElement(el);
1920                   LayoutBreak* lb = toLayoutBreak(el);
1921                   MeasureBase* mb = lb->measure();
1922                   Measure* m = mb && mb->isMeasure() ? toMeasure(mb) : nullptr;
1923                   if (m && m->isMMRest()) {
1924                         // propagate to original measure
1925                         m = m->mmRestLast();
1926                         for (Element* e : m->el()) {
1927                               if (e->isLayoutBreak()) {
1928                                     undoRemoveElement(e);
1929                                     break;
1930                                     }
1931                               }
1932                         }
1933                   }
1934                   break;
1935 
1936             case ElementType::CLEF:
1937                   {
1938                   Clef* clef = toClef(el);
1939                   Measure* m = clef->measure();
1940                   if (m->isMMRest()) {
1941                         // propagate to original measure
1942                         m = m->mmRestLast();
1943                         Segment* s = m->findSegment(SegmentType::Clef, clef->segment()->tick());
1944                         if (s && s->element(clef->track())) {
1945                               Clef* c = toClef(s->element(clef->track()));
1946                               undoRemoveElement(c);
1947                               }
1948                         }
1949                   else {
1950                         if (clef->generated()) {
1951                               // find the real clef if this is a cautionary one
1952                               if (m && m->prevMeasure()) {
1953                                     Fraction tick = m->tick();
1954                                     m = m->prevMeasure();
1955                                     Segment* s = m->findSegment(SegmentType::Clef, tick);
1956                                     if (s && s->element(clef->track()))
1957                                           clef = toClef(s->element(clef->track()));
1958                                     }
1959                               }
1960                         undoRemoveElement(clef);
1961                         }
1962                   }
1963                   break;
1964 
1965             case ElementType::MEASURE_NUMBER:
1966                   {
1967                   Measure* mea = toMeasure(el->parent());
1968                   switch (mea->measureNumberMode()) {
1969                         // If the user tries to remove an automatically generated measure number,
1970                         // we should force the measure not to show any measure number
1971                         case MeasureNumberMode::AUTO:
1972                               mea->undoChangeProperty(Pid::MEASURE_NUMBER_MODE, static_cast<int>(MeasureNumberMode::HIDE));
1973                               break;
1974 
1975                         // If the user tries to remove a measure number that he added manually,
1976                         // then we should set the MeasureNumberMode to AUTO only if will not show if set to auto.
1977                         // If after setting the MeasureNumberMode to AUTO, the measure number still shows,
1978                         // We need to force the measure to hide its measure number.
1979                         case MeasureNumberMode::SHOW:
1980                               if (mea->showsMeasureNumberInAutoMode())
1981                                     mea->undoChangeProperty(Pid::MEASURE_NUMBER_MODE, static_cast<int>(MeasureNumberMode::HIDE));
1982                               else
1983                                     mea->undoChangeProperty(Pid::MEASURE_NUMBER_MODE, static_cast<int>(MeasureNumberMode::AUTO));
1984                               break;
1985                         case MeasureNumberMode::HIDE:
1986                               break;
1987                         }
1988                   }
1989                   break;
1990             case ElementType::REHEARSAL_MARK:
1991             case ElementType::TEMPO_TEXT:
1992                   {
1993                   Segment* s = toSegment(el->parent());
1994                   Measure* m = s->measure();
1995                   if (m->isMMRest()) {
1996                         // propagate to original measure/element
1997                         m = m->mmRestFirst();
1998                         Segment* ns = m->findSegment(SegmentType::ChordRest, s->tick());
1999                         for (Element* e : ns->annotations()) {
2000                               if (e->type() == el->type() && e->track() == el->track()) {
2001                                     el = e;
2002                                     undoRemoveElement(el);
2003                                     break;
2004                                     }
2005                               }
2006                         }
2007                   else
2008                         undoRemoveElement(el);
2009                   }
2010                   break;
2011 
2012             case ElementType::OTTAVA_SEGMENT:
2013             case ElementType::HAIRPIN_SEGMENT:
2014             case ElementType::TRILL_SEGMENT:
2015             case ElementType::VIBRATO_SEGMENT:
2016             case ElementType::TEXTLINE_SEGMENT:
2017             case ElementType::VOLTA_SEGMENT:
2018             case ElementType::SLUR_SEGMENT:
2019             case ElementType::TIE_SEGMENT:
2020             case ElementType::LYRICSLINE_SEGMENT:
2021             case ElementType::PEDAL_SEGMENT:
2022             case ElementType::GLISSANDO_SEGMENT:
2023             case ElementType::LET_RING_SEGMENT:
2024             case ElementType::PALM_MUTE_SEGMENT:
2025                   {
2026                   el = toSpannerSegment(el)->spanner();
2027                   undoRemoveElement(el);
2028                   }
2029                   break;
2030 
2031             case ElementType::STEM_SLASH:           // cannot delete this elements
2032             case ElementType::HOOK:
2033                   qDebug("cannot remove %s", el->name());
2034                   break;
2035 
2036             case ElementType::TEXT:
2037                   if ((el->parent() && el->parent()->isTBox()) || el->isTBox())
2038                         el->undoChangeProperty(Pid::TEXT, QString());
2039                   else
2040                         undoRemoveElement(el);
2041                   break;
2042 
2043             case ElementType::INSTRUMENT_CHANGE:
2044                   {
2045                   InstrumentChange* ic = static_cast<InstrumentChange*>(el);
2046                   Fraction tickStart = ic->segment()->tick();
2047                   Part* part = ic->part();
2048                   Interval oldV = part->instrument(tickStart)->transpose();
2049                   undoRemoveElement(el);
2050                   for (KeySig* keySig : ic->keySigs())
2051                         deleteItem(keySig);
2052                   for (Clef* clef : ic->clefs())
2053                         deleteItem(clef);
2054                   if (part->instrument(tickStart)->transpose() != oldV) {
2055                         auto i = part->instruments()->upper_bound(tickStart.ticks());
2056                         Fraction tickEnd;
2057                         if (i == part->instruments()->end())
2058                               tickEnd = Fraction(-1, 1);
2059                         else
2060                               tickEnd = Fraction::fromTicks(i->first);
2061                         transpositionChanged(part, oldV, tickStart, tickEnd);
2062                         }
2063                   }
2064                   break;
2065 
2066             case ElementType::MARKER:
2067                   {
2068                   Measure* m = toMeasure(el->parent());
2069                   if (m->isMMRest()) {
2070                         // find corresponding marker in underlying measure
2071                         bool found = false;
2072                         // the marker may be in the first measure...
2073                         for (Element* e : m->mmRestFirst()->el()) {
2074                               if (e->isMarker() && e->subtype() == el->subtype()) {
2075                                     undoRemoveElement(e);
2076                                     found = true;
2077                                     break;
2078                                     }
2079                               }
2080                         if (!found) {
2081                               // ...or it may be in the last measure
2082                               for (Element* e : m->mmRestLast()->el()) {
2083                                     if (e->isMarker() && e->subtype() == el->subtype()) {
2084                                           undoRemoveElement(e);
2085                                           break;
2086                                           }
2087                                     }
2088                               }
2089                         }
2090                   // whether m is an mmrest or not, we still need to remove el
2091                   undoRemoveElement(el);
2092                   }
2093                   break;
2094 
2095             case ElementType::JUMP:
2096                   {
2097                   Measure* m = toMeasure(el->parent());
2098                   if (m->isMMRest()) {
2099                         // find corresponding jump in underlying measure
2100                         for (Element* e : m->mmRestLast()->el()) {
2101                               if (e->isJump() && e->subtype() == el->subtype()) {
2102                                     undoRemoveElement(e);
2103                                     break;
2104                                     }
2105                               }
2106                         }
2107                   // whether m is an mmrest or not, we still need to remove el
2108                   undoRemoveElement(el);
2109                   }
2110                   break;
2111 
2112             default:
2113                   undoRemoveElement(el);
2114                   break;
2115             }
2116       }
2117 
2118 //---------------------------------------------------------
2119 //   deleteMeasures
2120 //---------------------------------------------------------
2121 
deleteMeasures(MeasureBase * is,MeasureBase * ie,bool preserveTies)2122 void Score::deleteMeasures(MeasureBase* is, MeasureBase* ie, bool preserveTies)
2123       {
2124 // qDebug("deleteMeasures %p %p", is, ie);
2125 
2126 #if 0
2127       if (!selection().isRange())
2128             return;
2129 
2130       MeasureBase* is = selection().startSegment()->measure();
2131       if (is->isMeasure() && toMeasure(is)->isMMRest())
2132             is = toMeasure(is)->mmRestFirst();
2133       Segment* seg    = selection().endSegment();
2134       MeasureBase* ie;
2135 
2136       // choose the correct last measure based on the end segment
2137       // this depends on whether a whole measure is selected or only a few notes within it
2138       if (seg)
2139             ie = seg->prev() ? seg->measure() : seg->measure()->prev();
2140       else
2141             ie = lastMeasure();
2142 #endif
2143 
2144       select(0, SelectType::SINGLE, 0);
2145 
2146       // createEndBar if last measure is deleted
2147       bool createEndBar = false;
2148       if (ie->isMeasure()) {
2149             Measure* iem = toMeasure(ie);
2150             if (iem->isMMRest())
2151                   ie = /*iem = */iem->mmRestLast();
2152 //TODO            createEndBar = (iem == lastMeasureMM()) && (iem->endBarLineType() == BarLineType::END);
2153             createEndBar = false;
2154             }
2155 
2156 
2157       // get the last deleted timesig & keysig in order to restore after deletion
2158       KeySigEvent lastDeletedKeySigEvent;
2159       TimeSig* lastDeletedSig   = 0;
2160       KeySig* lastDeletedKeySig = 0;
2161       bool transposeKeySigEvent = false;
2162 
2163       for (MeasureBase* mb = ie;; mb = mb->prev()) {
2164             if (mb->isMeasure()) {
2165                   Measure* m = toMeasure(mb);
2166                   Segment* sts = m->findSegment(SegmentType::TimeSig, m->tick());
2167                   if (sts && !lastDeletedSig)
2168                         lastDeletedSig = toTimeSig(sts->element(0));
2169                   sts = m->findSegment(SegmentType::KeySig, m->tick());
2170                   if (sts && !lastDeletedKeySig) {
2171                         lastDeletedKeySig = toKeySig(sts->element(0));
2172                         if (lastDeletedKeySig) {
2173                               lastDeletedKeySigEvent = lastDeletedKeySig->keySigEvent();
2174                               if (!styleB(Sid::concertPitch) && !lastDeletedKeySigEvent.isAtonal() && !lastDeletedKeySigEvent.custom()) {
2175                                     // convert to concert pitch
2176                                     transposeKeySigEvent = true;
2177                                     Interval v = staff(0)->part()->instrument(m->tick())->transpose();
2178                                     if (!v.isZero())
2179                                           lastDeletedKeySigEvent.setKey(transposeKey(lastDeletedKeySigEvent.key(), v, lastDeletedKeySig->part()->preferSharpFlat()));
2180                                     }
2181                               }
2182                         }
2183                   if (lastDeletedSig && lastDeletedKeySig)
2184                         break;
2185                   }
2186             if (mb == is)
2187                   break;
2188             }
2189       Fraction startTick = is->tick();
2190       Fraction endTick   = ie->tick();
2191 
2192       undoInsertTime(is->tick(), -(ie->endTick() - is->tick()));
2193       for (Score* score : scoreList()) {
2194             Measure* mis = score->tick2measure(startTick);
2195             Measure* mie = score->tick2measure(endTick);
2196 
2197             score->undoRemoveMeasures(mis, mie, preserveTies);
2198 
2199             // adjust views
2200             Measure* focusOn = mis->prevMeasure() ? mis->prevMeasure() : score->firstMeasure();
2201             for (MuseScoreView* v : qAsConst(score->viewer))
2202                   v->adjustCanvasPosition(focusOn, false);
2203 
2204             if (createEndBar) {
2205 //                  Measure* lastMeasure = score->lastMeasure();
2206 //TODO                  if (lastMeasure && lastMeasure->endBarLineType() == BarLineType::NORMAL)
2207 //                        score->undoChangeEndBarLineType(lastMeasure, BarLineType::END);
2208                   }
2209 
2210             // insert correct timesig after deletion
2211             Measure* mBeforeSel = mis->prevMeasure();
2212             Measure* mAfterSel  = mBeforeSel ? mBeforeSel->nextMeasure() : score->firstMeasure();
2213             if (mAfterSel && lastDeletedSig) {
2214                   bool changed = true;
2215                   if (mBeforeSel) {
2216                         if (mBeforeSel->timesig() == mAfterSel->timesig()) {
2217                               changed = false;
2218                               }
2219                         }
2220                   Segment* s = mAfterSel->findSegment(SegmentType::TimeSig, mAfterSel->tick());
2221                   if (!s && changed) {
2222                         Segment* ns = mAfterSel->undoGetSegment(SegmentType::TimeSig, mAfterSel->tick());
2223                         for (int staffIdx = 0; staffIdx < score->nstaves(); staffIdx++) {
2224                               TimeSig* nts = new TimeSig(score);
2225                               nts->setTrack(staffIdx * VOICES);
2226                               nts->setParent(ns);
2227                               nts->setSig(lastDeletedSig->sig(), lastDeletedSig->timeSigType());
2228                               score->undoAddElement(nts);
2229                               }
2230                         }
2231                   }
2232             // insert correct keysig if necessary
2233             if (mAfterSel && !mBeforeSel && lastDeletedKeySig) {
2234                   Segment* s = mAfterSel->findSegment(SegmentType::KeySig, mAfterSel->tick());
2235                   if (!s) {
2236                         Segment* ns = mAfterSel->undoGetSegment(SegmentType::KeySig, mAfterSel->tick());
2237                         for (int staffIdx = 0; staffIdx < score->nstaves(); staffIdx++) {
2238                               KeySigEvent nkse = lastDeletedKeySigEvent;
2239                               if (transposeKeySigEvent) {
2240                                     Interval v = score->staff(staffIdx)->part()->instrument(Fraction(0,1))->transpose();
2241                                     v.flip();
2242                                     nkse.setKey(transposeKey(nkse.key(), v, lastDeletedKeySig->part()->preferSharpFlat()));
2243                                     }
2244                               KeySig* nks = new KeySig(score);
2245                               nks->setTrack(staffIdx * VOICES);
2246                               nks->setParent(ns);
2247                               nks->setKeySigEvent(nkse);
2248                               score->undoAddElement(nks);
2249                               }
2250                         }
2251                   }
2252             }
2253 
2254       _is.setSegment(0);        // invalidate position
2255       }
2256 
2257 //---------------------------------------------------------
2258 //   deleteSpannersFromRange
2259 ///   Deletes spanners in the given range that match the
2260 ///   given selection filter.
2261 //---------------------------------------------------------
2262 
deleteSpannersFromRange(const Fraction & t1,const Fraction & t2,int track1,int track2,const SelectionFilter & filter)2263 void Score::deleteSpannersFromRange(const Fraction& t1, const Fraction& t2, int track1, int track2, const SelectionFilter& filter)
2264       {
2265       auto spanners = _spanner.findOverlapping(t1.ticks(), t2.ticks() - 1);
2266       for (auto i : spanners) {
2267             Spanner* sp = i.value;
2268             if (sp->isVolta())
2269                   continue;
2270             if (!filter.canSelectVoice(sp->track()))
2271                   continue;
2272             if (sp->track() >= track1 && sp->track() < track2) {
2273                   if (sp->tick() >= t1 && sp->tick() < t2
2274                      && sp->tick2() >= t1 && sp->tick2() <= t2) {
2275                         undoRemoveElement(sp);
2276                         }
2277                   else if (sp->isSlur() && ((sp->tick() >= t1 && sp->tick() < t2)
2278                      || (sp->tick2() >= t1 && sp->tick2() < t2))) {
2279                         undoRemoveElement(sp);
2280                         }
2281                   }
2282             }
2283       }
2284 
2285 //---------------------------------------------------------
2286 //   deleteAnnotationsFromRange
2287 ///   Deletes annotations in the given range that match the
2288 ///   given selection filter.
2289 //---------------------------------------------------------
2290 
deleteAnnotationsFromRange(Segment * s1,Segment * s2,int track1,int track2,const SelectionFilter & filter)2291 void Score::deleteAnnotationsFromRange(Segment* s1, Segment* s2, int track1, int track2, const SelectionFilter& filter)
2292       {
2293       if (!s1)
2294             return;
2295       if (s2 && (*s2) < (*s1))
2296             return;
2297 
2298       for (int track = track1; track < track2; ++track) {
2299             if (!filter.canSelectVoice(track))
2300                   continue;
2301             for (Segment* s = s1; s && s != s2; s = s->next1()) {
2302                   const auto annotations = s->annotations(); // make a copy since we alter the list
2303                   for (Element* annotation : annotations) {
2304                         // skip if not included in selection (eg, filter)
2305                         if (!filter.canSelect(annotation))
2306                               continue;
2307                         if (!annotation->systemFlag() && annotation->track() == track)
2308                               deleteItem(annotation);
2309                         }
2310                   }
2311             }
2312       }
2313 
2314 //---------------------------------------------------------
2315 //   deleteRange
2316 ///   Deletes elements in the given range that match the
2317 ///   given selection filter.
2318 ///   \return A chord/rest inside the selected range
2319 ///   that can be used to establish a selection after this
2320 ///   deletion operation.
2321 //---------------------------------------------------------
2322 
deleteRange(Segment * s1,Segment * s2,int track1,int track2,const SelectionFilter & filter)2323 ChordRest* Score::deleteRange(Segment* s1, Segment* s2, int track1, int track2, const SelectionFilter& filter)
2324       {
2325       ChordRest* cr = nullptr;
2326 
2327       if (s1) {
2328             // delete content from measures underlying mmrests
2329             if (s1 && s1->measure() && s1->measure()->isMMRest())
2330                   s1 = s1->measure()->mmRestFirst()->first();
2331             if (s2 && s2->measure() && s2->measure()->isMMRest())
2332                   s2 = s2->measure()->mmRestLast()->last();
2333 
2334             const Fraction stick1 = s1->tick();
2335             const Fraction stick2 = s2 ? s2->tick() : lastMeasure()->endTick();
2336 
2337             Segment* ss1 = s1;
2338             if (!ss1->isChordRestType())
2339                   ss1 = ss1->next1(SegmentType::ChordRest);
2340             bool fullMeasure = ss1 && (ss1->measure()->first(SegmentType::ChordRest) == ss1)
2341                   && (s2 == 0 || s2->isEndBarLineType());
2342 
2343             Fraction tick2 = s2 ? s2->tick() : Fraction(INT_MAX, 1);
2344 
2345             deleteSpannersFromRange(stick1, stick2, track1, track2, filter);
2346 
2347             for (int track = track1; track < track2; ++track) {
2348                   if (!filter.canSelectVoice(track))
2349                         continue;
2350                   Fraction f;
2351                   Fraction tick  = Fraction(-1, 1);
2352                   Tuplet* tuplet = 0;
2353                   for (Segment* s = s1; s && (s->tick() < stick2); s = s->next1()) {
2354                         if (s->element(track) && s->isBreathType()) {
2355                               deleteItem(s->element(track));
2356                               continue;
2357                               }
2358                         // delete annotations just from this segment and track
2359                         deleteAnnotationsFromRange(s, s->next1(), track, track + 1, filter);
2360 
2361                         Element* e = s->element(track);
2362                         if (!e)
2363                               continue;
2364                         if (!s->isChordRestType()) {
2365                               // do not delete TimeSig/KeySig,
2366                               // it doesn't make sense to do it, except on full system
2367                               if (s->segmentType() != SegmentType::TimeSig && s->segmentType() != SegmentType::KeySig) {
2368                                     if (!(e->isBarLine()))
2369                                           undoRemoveElement(e);
2370                                     }
2371                               continue;
2372                               }
2373                         ChordRest* cr1 = toChordRest(e);
2374                         if (tick == Fraction(-1, 1)) {
2375                               // first ChordRest found:
2376                               Fraction offset = cr1->rtick();
2377                               if (cr1->measure()->tick() >= s1->tick() && offset.isNotZero()) {
2378                                     f = offset;
2379                                     tick = s->measure()->tick();
2380                                     }
2381                               else {
2382                                     tick = s->tick();
2383                                     f    = Fraction(0, 1);
2384                                     }
2385                               tuplet = cr1->tuplet();
2386                               if (tuplet && (tuplet->tick() == tick) && ((tuplet->tick() + tuplet->actualTicks()) <= tick2) ) {
2387                                     // remove complete top level tuplet
2388 
2389                                     Tuplet* t = cr1->tuplet();
2390                                     while (t->tuplet())
2391                                           t = t->tuplet();
2392                                     cmdDeleteTuplet(t, false);
2393                                     f += t->ticks();
2394                                     tuplet = 0;
2395                                     continue;
2396                                     }
2397                               }
2398                         if (tuplet != cr1->tuplet()) {
2399                               Tuplet* t = cr1->tuplet();
2400                               if (t && (((t->tick() + t->actualTicks()) <= tick2) || fullMeasure)) {
2401                                     // remove complete top level tuplet
2402 
2403                                     while (t->tuplet())
2404                                           t = t->tuplet();
2405                                     cmdDeleteTuplet(t, false);
2406                                     f += t->ticks();
2407                                     tuplet = 0;
2408                                     continue;
2409                                     }
2410                               if (f.isValid())
2411                                     setRest(tick, track, f, false, tuplet);
2412                               tick = cr1->tick();
2413                               tuplet = cr1->tuplet();
2414                               removeChordRest(cr1, true);
2415                               f = cr1->ticks();
2416                               }
2417                         else {
2418                               removeChordRest(cr1, true);
2419                               f += cr1->ticks();
2420                               }
2421                         }
2422                   if (f.isValid() && !f.isZero()) {
2423                         if (fullMeasure) {
2424                               // handle this as special case to be able to
2425                               // fix broken measures:
2426                               Staff* staff = Score::staff(track / VOICES);
2427                               for (Measure* m = s1->measure(); m; m = m->nextMeasure()) {
2428                                     Fraction tick3   = m->tick();
2429                                     Fraction ff = m->stretchedLen(staff);
2430                                     Rest* r = setRest(tick3, track, ff, false, 0);
2431                                     if (!cr)
2432                                           cr = r;
2433                                     if (s2 && (m == s2->measure()))
2434                                           break;
2435                                     }
2436                               }
2437                         else {
2438                               Rest* r = setRest(tick, track, f, false, tuplet);
2439                               if (!cr)
2440                                     cr = r;
2441                               }
2442                         }
2443                   }
2444             }
2445       return cr;
2446       }
2447 
2448 //---------------------------------------------------------
2449 //   cmdDeleteSelection
2450 //---------------------------------------------------------
2451 
cmdDeleteSelection()2452 void Score::cmdDeleteSelection()
2453       {
2454       ChordRest* cr = 0;            // select something after deleting notes
2455 
2456       if (selection().isRange()) {
2457             Segment* s1 = selection().startSegment();
2458             Segment* s2 = selection().endSegment();
2459             const Fraction stick1 = selection().tickStart();
2460             const Fraction stick2 = selection().tickEnd();
2461             cr = deleteRange(s1, s2, staff2track(selection().staffStart()), staff2track(selection().staffEnd()), selectionFilter());
2462             s1 = tick2segment(stick1);
2463             s2 = tick2segment(stick2, true);
2464             if (s1 == 0 || s2 == 0)
2465                   deselectAll();
2466             else {
2467                   _selection.setStartSegment(s1);
2468                   _selection.setEndSegment(s2);
2469                   _selection.updateSelectedElements();
2470                   }
2471             }
2472       else {
2473             // deleteItem modifies selection().elements() list,
2474             // so we need a local copy:
2475             QList<Element*> el = selection().elements();
2476 
2477             // keep track of linked elements that are deleted implicitly
2478             // so we don't try to delete them twice if they are also in selection
2479             QList<ScoreElement*> deletedElements;
2480             // Similarly, deleting one spanner segment, will delete all of them
2481             // so we don't try to delete them twice if they are also in selection
2482             QList<Spanner*> deletedSpanners;
2483 
2484             for (Element* e : el) {
2485                   // these are the linked elements we are about to delete
2486                   QList<ScoreElement*> links;
2487                   if (e->links())
2488                         links = *e->links();
2489 
2490                   // find location of element to select after deleting notes
2491                   // get tick of element itself if that is valid
2492                   // or of spanner or parent if that is more valid
2493                   Fraction tick  = { -1, 1 };
2494                   int track = -1;
2495                   if (!cr) {
2496                         if (e->isNote())
2497                               tick = toNote(e)->chord()->tick();
2498                         else if (e->isRest())
2499                               tick = toRest(e)->tick();
2500                         else if (e->isSpannerSegment())
2501                               tick = toSpannerSegment(e)->spanner()->tick();
2502                         else if (e->parent()
2503                            && (e->parent()->isSegment() || e->parent()->isChord() || e->parent()->isNote() || e->parent()->isRest()))
2504                               tick = e->parent()->tick();
2505                         //else tick < 0
2506                         track = e->track();
2507                         }
2508 
2509                   // delete element if we have not done so already
2510                   if (!deletedElements.contains(e)) {
2511                         // do not delete two spanner segments from the same spanner
2512                         if (e->isSpannerSegment()) {
2513                               Spanner* spanner = toSpannerSegment(e)->spanner();
2514                               if (deletedSpanners.contains(spanner))
2515                                     continue;
2516                               else {
2517                                     QList<ScoreElement*> linkedSpanners;
2518                                     if (spanner->links())
2519                                           linkedSpanners = *spanner->links();
2520                                     else
2521                                           linkedSpanners.append(spanner);
2522                                     for (ScoreElement* se : qAsConst(linkedSpanners))
2523                                           deletedSpanners.append(toSpanner(se));
2524                                     }
2525                               }
2526                         deleteItem(e);
2527                         }
2528 
2529                   // find element to select
2530                   if (!cr && tick >= Fraction(0,1) && track >= 0)
2531                         cr = findCR(tick, track);
2532 
2533                   // add these linked elements to list of already-deleted elements
2534                   for (ScoreElement* se : qAsConst(links))
2535                         deletedElements.append(se);
2536                   }
2537 
2538             }
2539 
2540       deselectAll();
2541       // make new selection if appropriate
2542       if (noteEntryMode())
2543             cr = _is.cr();
2544       if (cr) {
2545             if (cr->isChord())
2546                   select(toChord(cr)->upNote(), SelectType::SINGLE);
2547             else
2548                   select(cr, SelectType::SINGLE);
2549             }
2550       }
2551 
2552 //---------------------------------------------------------
2553 //   cmdFullMeasureRest
2554 //---------------------------------------------------------
2555 
cmdFullMeasureRest()2556 void Score::cmdFullMeasureRest()
2557       {
2558       Segment* s1     = nullptr;
2559       Segment* s2     = nullptr;
2560       Fraction stick1 = { -1, 1 };
2561       Fraction stick2 = { -1, 1 };
2562       int track1      = -1;
2563       int track2      = -1;
2564       Rest* r         = nullptr;
2565 
2566       if (noteEntryMode()) {
2567             s1 = inputState().segment();
2568             if (!s1 || s1->rtick().isNotZero())
2569                   return;
2570             Measure* m = s1->measure();
2571             s2 = m->last();
2572             stick1 = s1->tick();
2573             stick2 = s2->tick();
2574             track1 = inputState().track();
2575             track2 = track1 + 1;
2576             }
2577       else if (selection().isRange()) {
2578             s1 = selection().startSegment();
2579             s2 = selection().endSegment();
2580             if (styleB(Sid::createMultiMeasureRests)) {
2581                    // use underlying measures
2582                    if (s1 && s1->measure()->isMMRest())
2583                          s1 = tick2segment(stick1);
2584                    if (s2 && s2->measure()->isMMRest())
2585                          s2 = tick2segment(stick2, true);
2586                    }
2587             stick1 = selection().tickStart();
2588             stick2 = selection().tickEnd();
2589             Segment* ss1 = s1;
2590             if (ss1 && ss1->segmentType() != SegmentType::ChordRest)
2591                   ss1 = ss1->next1(SegmentType::ChordRest);
2592             bool fullMeasure = ss1 && (ss1->measure()->first(SegmentType::ChordRest) == ss1)
2593                   && (s2 == 0 || (s2->segmentType() == SegmentType::EndBarLine)
2594                         || (s2->segmentType() == SegmentType::TimeSigAnnounce)
2595                         || (s2->segmentType() == SegmentType::KeySigAnnounce));
2596             if (!fullMeasure) {
2597                   return;
2598                   }
2599             track1 = selection().staffStart() * VOICES;
2600             track2 = selection().staffEnd() * VOICES;
2601             }
2602       else if (selection().cr()) {
2603             ChordRest* cr = selection().cr();
2604             if (!cr || cr->rtick().isNotZero())
2605                   return;
2606             Measure* m = cr->measure();
2607             s1 = m->first();
2608             s2 = m->last();
2609             stick1 = s1->tick();
2610             stick2 = s2->tick();
2611             track1 = selection().cr()->track();
2612             track2 = track1 + 1;
2613             }
2614       else {
2615             return;
2616             }
2617 
2618       for (int track = track1; track < track2; ++track) {
2619             if (selection().isRange() && !selectionFilter().canSelectVoice(track))
2620                   continue;
2621             // first pass - remove non-initial rests from empty measures/voices
2622             for (Segment* s = s1; s != s2; s = s->next1()) {
2623                   if (!(s->measure()->isOnlyRests(track))) // Don't remove anything from measures that contain notes
2624                         continue;
2625                   if (s->segmentType() != SegmentType::ChordRest || !s->element(track))
2626                         continue;
2627                   ChordRest* cr = toChordRest(s->element(track));
2628                   // keep first rest of measure as placeholder (replaced in second pass)
2629                   // but delete all others
2630                   if (s->rtick().isNotZero())
2631                         removeChordRest(cr, true);
2632                   }
2633             // second pass - replace placeholders with full measure rests
2634             for (Measure* m = s1->measure(); m; m = m->nextMeasure()) {
2635                   if (m->isOnlyRests(track)) {
2636                         ChordRest* cr = m->findChordRest(m->tick(), track);
2637                         if (cr) {
2638                               removeChordRest(cr, true);
2639                               r = addRest(m->tick(), track, TDuration(TDuration::DurationType::V_MEASURE), 0);
2640                               }
2641                         else if (noteEntryMode()) {
2642                               // might be no cr at input position
2643                               r = addRest(m->tick(), track, TDuration(TDuration::DurationType::V_MEASURE), 0);
2644                               }
2645                         }
2646                   if (s2 && (m == s2->measure()))
2647                         break;
2648                   }
2649             }
2650 
2651       // selected range is probably empty now and possibly subsumed by an mmrest
2652       // so updating selection requires forcing mmrests to be updated first
2653 //TODO-ws      if (styleB(Sid::createMultiMeasureRests))
2654 //            createMMRests();
2655       s1 = tick2segmentMM(stick1);
2656       s2 = tick2segmentMM(stick2, true);
2657       if (selection().isRange() && s1 && s2) {
2658             _selection.setStartSegment(s1);
2659             _selection.setEndSegment(s2);
2660             _selection.updateSelectedElements();
2661             }
2662       else if (r) {
2663             // note entry mode
2664             select(r, SelectType::SINGLE);
2665             }
2666       else {
2667             deselectAll();
2668             }
2669       }
2670 
2671 //---------------------------------------------------------
2672 //   addLyrics
2673 //    called from Keyboard Accelerator & menu
2674 //---------------------------------------------------------
2675 
addLyrics()2676 Lyrics* Score::addLyrics()
2677       {
2678       Element* el = selection().element();
2679       if (el == 0 || (!el->isNote() && !el->isLyrics() && !el->isRest())) {
2680             MScore::setError(NO_LYRICS_SELECTED);
2681             return 0;
2682             }
2683       ChordRest* cr;
2684       if (el->isNote()) {
2685             cr = toNote(el)->chord();
2686             if(cr->isGrace())
2687                   cr = toChordRest(cr->parent());
2688             }
2689       else if (el->isLyrics())
2690             cr = toLyrics(el)->chordRest();
2691       else if (el->isRest())
2692             cr = toChordRest(el);
2693       else
2694             return 0;
2695 
2696       int no = int(cr->lyrics().size());
2697       Lyrics* lyrics = new Lyrics(this);
2698       lyrics->setTrack(cr->track());
2699       lyrics->setParent(cr);
2700       lyrics->setNo(no);
2701       undoAddElement(lyrics);
2702       select(lyrics, SelectType::SINGLE, 0);
2703       return lyrics;
2704       }
2705 
2706 //---------------------------------------------------------
2707 //   addHairpin
2708 //---------------------------------------------------------
2709 
addHairpin(HairpinType t,const Fraction & tickStart,const Fraction & tickEnd,int track)2710 Hairpin* Score::addHairpin(HairpinType t, const Fraction& tickStart, const Fraction& tickEnd, int track)
2711       {
2712       Hairpin* pin = new Hairpin(this);
2713       pin->setHairpinType(t);
2714       if (t == HairpinType::CRESC_LINE) {
2715             pin->setBeginText("cresc.");
2716             pin->setContinueText("(cresc.)");
2717             }
2718       else if (t == HairpinType::DECRESC_LINE) {
2719             pin->setBeginText("dim.");
2720             pin->setContinueText("(dim.)");
2721             }
2722       pin->setTrack(track);
2723       pin->setTrack2(track);
2724       pin->setTick(tickStart);
2725       pin->setTick2(tickEnd);
2726       undoAddElement(pin);
2727       return pin;
2728       }
2729 
2730 //---------------------------------------------------------
2731 //   Score::addHairpin
2732 //---------------------------------------------------------
2733 
addHairpin(HairpinType type,ChordRest * cr1,ChordRest * cr2,bool toCr2End)2734 Hairpin* Score::addHairpin(HairpinType type, ChordRest* cr1, ChordRest* cr2, bool toCr2End)
2735       {
2736       if (!cr1)
2737             return nullptr;
2738       if (!cr2)
2739             cr2 = cr1;
2740       Q_ASSERT(cr1->staffIdx() == cr2->staffIdx());
2741       const Fraction end = toCr2End ? cr2->tick() + cr2->actualTicks() : cr2->tick();
2742       return addHairpin(type, cr1->tick(), end, cr1->track());
2743       }
2744 
2745 //---------------------------------------------------------
2746 //   cmdCreateTuplet
2747 //    replace cr with tuplet
2748 //---------------------------------------------------------
2749 
cmdCreateTuplet(ChordRest * ocr,Tuplet * tuplet)2750 void Score::cmdCreateTuplet(ChordRest* ocr, Tuplet* tuplet)
2751       {
2752       int track        = ocr->track();
2753       Measure* measure = ocr->measure();
2754       Fraction tick     = ocr->tick();
2755 
2756       if (ocr->tuplet())
2757             tuplet->setTuplet(ocr->tuplet());
2758       undoRemoveElement(ocr);
2759 
2760       ChordRest* cr;
2761       if (ocr->isChord()) {
2762             cr = new Chord(this);
2763             foreach (Note* oldNote, toChord(ocr)->notes()) {
2764                   Note* note = new Note(this);
2765                   note->setPitch(oldNote->pitch());
2766                   note->setTpc1(oldNote->tpc1());
2767                   note->setTpc2(oldNote->tpc2());
2768                   cr->add(note);
2769                   }
2770             }
2771       else
2772             cr = new Rest(this);
2773 
2774       Fraction an     = (tuplet->ticks() * tuplet->ratio()) / tuplet->baseLen().fraction();
2775       int actualNotes = an.numerator() / an.denominator();
2776 
2777       tuplet->setTrack(track);
2778       cr->setTuplet(tuplet);
2779       cr->setTrack(track);
2780       cr->setDurationType(tuplet->baseLen());
2781       cr->setTicks(tuplet->baseLen().fraction());
2782 
2783       undoAddCR(cr, measure, tick);
2784 
2785       Fraction ticks = cr->actualTicks();
2786 
2787       for (int i = 0; i < (actualNotes-1); ++i) {
2788             tick += ticks;
2789             Rest* rest = new Rest(this);
2790             rest->setTuplet(tuplet);
2791             rest->setTrack(track);
2792             rest->setDurationType(tuplet->baseLen());
2793             rest->setTicks(tuplet->baseLen().fraction());
2794             undoAddCR(rest, measure, tick);
2795             }
2796       }
2797 
2798 //---------------------------------------------------------
2799 //   colorItem
2800 //---------------------------------------------------------
2801 
colorItem(Element * element)2802 void Score::colorItem(Element* element)
2803       {
2804       QColor sc(element->color());
2805       QColor c = QColorDialog::getColor(sc);
2806       if (!c.isValid())
2807             return;
2808 
2809       for (Element* e : selection().elements()) {
2810             if (e->color() != c) {
2811                   e->undoChangeProperty(Pid::COLOR, c);
2812                   e->setGenerated(false);
2813                   addRefresh(e->abbox());
2814                   if (e->isBarLine()) {
2815 //                        Element* ep = e->parent();
2816 //                        if (ep->isSegment() && toSegment(ep)->isEndBarLineType()) {
2817 //                              Measure* m = toSegment(ep)->measure();
2818 //                              BarLine* bl = toBarLine(e);
2819 //                              m->setEndBarLineType(bl->barLineType(), false, e->visible(), e->color());
2820 //                              }
2821                         }
2822                   }
2823             }
2824       deselectAll();
2825       }
2826 
2827 //---------------------------------------------------------
2828 //   cmdExchangeVoice
2829 //---------------------------------------------------------
2830 
cmdExchangeVoice(int s,int d)2831 void Score::cmdExchangeVoice(int s, int d)
2832       {
2833       if (!selection().isRange()) {
2834             MScore::setError(NO_STAFF_SELECTED);
2835             return;
2836             }
2837       Fraction t1 = selection().tickStart();
2838       Fraction t2 = selection().tickEnd();
2839 
2840       Measure* m1 = tick2measure(t1);
2841       Measure* m2 = tick2measure(t2);
2842 
2843       if (selection().score()->excerpt())
2844             return;
2845 
2846       if (t2 > m2->tick())
2847             m2 = m2->nextMeasure();
2848 
2849       for (;;) {
2850             undoExchangeVoice(m1, s, d, selection().staffStart(), selection().staffEnd());
2851             m1 = m1->nextMeasure();
2852             if ((m1 == 0) || (m2 && (m1->tick() == m2->tick())))
2853                   break;
2854             }
2855       }
2856 
2857 //---------------------------------------------------------
2858 //   cmdEnterRest
2859 //---------------------------------------------------------
2860 
cmdEnterRest(const TDuration & d)2861 void Score::cmdEnterRest(const TDuration& d)
2862       {
2863       if (_is.track() == -1) {
2864             qDebug("cmdEnterRest: track -1");
2865             return;
2866             }
2867       startCmd();
2868       enterRest(d);
2869       endCmd();
2870       }
2871 
2872 //---------------------------------------------------------
2873 //   enterRest
2874 //---------------------------------------------------------
2875 
enterRest(const TDuration & d,InputState * externalInputState)2876 void Score::enterRest(const TDuration& d, InputState* externalInputState)
2877       {
2878       InputState& is = externalInputState ? (*externalInputState) : _is;
2879 
2880       expandVoice(is.segment(), is.track());
2881 
2882       if (!is.cr()) {
2883             qDebug("cannot enter rest here");
2884             return;
2885             }
2886 
2887       const int track = is.track();
2888       NoteVal nval;
2889       setNoteRest(is.segment(), track, nval, d.fraction(), Direction::AUTO, /* forceAccidental */ false, /* rhythmic */ false, externalInputState);
2890       is.moveToNextInputPos();
2891       if (!is.noteEntryMode() || is.usingNoteEntryMethod(NoteEntryMethod::STEPTIME))
2892             is.setRest(false);  // continue with normal note entry
2893       }
2894 
2895 //---------------------------------------------------------
2896 //   removeChordRest
2897 //    remove chord or rest
2898 //    remove associated segment if empty
2899 //    remove beam
2900 //    remove slurs
2901 //---------------------------------------------------------
2902 
removeChordRest(ChordRest * cr,bool clearSegment)2903 void Score::removeChordRest(ChordRest* cr, bool clearSegment)
2904       {
2905       QList<Segment*> segments;
2906       for (ScoreElement* e : cr->linkList()) {
2907             undo(new RemoveElement(static_cast<Element*>(e)));
2908             if (clearSegment) {
2909                   Segment* s = cr->segment();
2910                   if (!segments.contains(s))
2911                         segments.append(s);
2912                   }
2913             }
2914       for (Segment* s : segments) {
2915             if (s->empty())
2916                   undo(new RemoveElement(s));
2917             }
2918       if (cr->beam()) {
2919             Beam* beam = cr->beam();
2920             if (beam->generated()) {
2921                   beam->parent()->remove(beam);
2922                   delete beam;
2923                   }
2924             else
2925                   undoRemoveElement(beam);
2926             }
2927       }
2928 
2929 //---------------------------------------------------------
2930 //   cmdDeleteTuplet
2931 //    remove tuplet and replace with rest
2932 //---------------------------------------------------------
2933 
cmdDeleteTuplet(Tuplet * tuplet,bool replaceWithRest)2934 void Score::cmdDeleteTuplet(Tuplet* tuplet, bool replaceWithRest)
2935       {
2936       foreach(DurationElement* de, tuplet->elements()) {
2937             if (de->isChordRest())
2938                   removeChordRest(toChordRest(de), true);
2939             else {
2940                   Q_ASSERT(de->isTuplet());
2941                   cmdDeleteTuplet(toTuplet(de), false);
2942                   }
2943             }
2944       if (replaceWithRest)
2945             setRest(tuplet->tick(), tuplet->track(), tuplet->ticks(), true, tuplet->tuplet());
2946       }
2947 
2948 //---------------------------------------------------------
2949 //   nextInputPos
2950 //---------------------------------------------------------
2951 
nextInputPos(ChordRest * cr,bool doSelect)2952 void Score::nextInputPos(ChordRest* cr, bool doSelect)
2953       {
2954       ChordRest* ncr = nextChordRest(cr);
2955       if ((ncr == 0) && (_is.track() % VOICES)) {
2956             Segment* s = tick2segment(cr->tick() + cr->actualTicks(), false, SegmentType::ChordRest);
2957             int track = (cr->track() / VOICES) * VOICES;
2958             ncr = s ? toChordRest(s->element(track)) : 0;
2959             }
2960       if (ncr) {
2961             _is.setSegment(ncr->segment());
2962             if (doSelect)
2963                   select(ncr, SelectType::SINGLE, 0);
2964             setPlayPos(ncr->tick());
2965             for (MuseScoreView* v : qAsConst(viewer))
2966                   v->moveCursor();
2967             }
2968       }
2969 
2970 //---------------------------------------------------------
2971 //   insertMeasure
2972 //    Create a new MeasureBase of type type and insert
2973 //    before measure.
2974 //    If measure is zero, append new MeasureBase.
2975 //---------------------------------------------------------
2976 
insertMeasure(ElementType type,MeasureBase * measure,bool createEmptyMeasures,bool moveSignaturesClef)2977 void Score::insertMeasure(ElementType type, MeasureBase* measure, bool createEmptyMeasures, bool moveSignaturesClef)
2978       {
2979       Fraction tick;
2980       if (measure) {
2981             if (measure->isMeasure() && toMeasure(measure)->isMMRest()) {
2982                   measure = toMeasure(measure)->prev();
2983                   measure = measure ? measure->next() : firstMeasure();
2984                   deselectAll();
2985                   }
2986             tick = measure->tick();
2987             }
2988       else
2989             tick = last() ? last()->endTick() : Fraction(0,1);
2990 
2991       Fraction f       = sigmap()->timesig(tick.ticks()).nominal(); // use nominal time signature of current measure
2992       Measure* om      = 0;                                       // measure base in "this" score
2993       MeasureBase* rmb = 0;                                       // measure base in root score (for linking)
2994       Fraction ticks   = { 0, 1 };
2995 
2996       for (Score* score : scoreList()) {
2997             MeasureBase* im = 0;
2998             if (measure) {
2999                   if (measure->isMeasure())
3000                         im = score->tick2measure(tick);
3001                   else {
3002                         if (!measure->links()) {
3003                               if (measure->score() == score)
3004                                     im = measure;
3005                               else
3006                                     qDebug("no links");
3007                               }
3008                         else {
3009                               for (ScoreElement* m : *measure->links()) {
3010                                     if (measure->score() == score) {
3011                                           im = toMeasureBase(m);
3012                                           break;
3013                                           }
3014                                     }
3015                               }
3016                         }
3017                   if (!im)
3018                         qDebug("measure not found");
3019                   }
3020             MeasureBase* mb = toMeasureBase(Element::create(type, score));
3021             mb->setTick(tick);
3022 
3023             if (im)
3024                   im = im->top(); // don't try to insert in front of nested frame
3025             mb->setNext(im);
3026             mb->setPrev(im ? im->prev() : score->last());
3027             if (mb->isMeasure()) {
3028                   Measure* m = toMeasure(mb);
3029                   m->setTimesig(f);
3030                   m->setTicks(f);
3031                   }
3032             undo(new InsertMeasures(mb, mb));
3033 
3034             if (type == ElementType::MEASURE) {
3035                   Measure* m  = toMeasure(mb);  // new measure
3036                   ticks       = m->ticks();
3037                   Measure* mi = nullptr;        // insert before
3038                   if (im) {
3039                         if (im->isMeasure())
3040                               mi = toMeasure(im);
3041                         else
3042                               mi = score->tick2measure(im->tick());
3043                         }
3044 
3045                   if (score->isMaster())
3046                         om = m;
3047 
3048                   QList<TimeSig*> tsl;
3049                   QList<KeySig*>  ksl;
3050                   QList<Clef*>    cl;
3051                   QList<Clef*>    pcl;
3052 
3053                   //
3054                   // remove clef, time and key signatures
3055                   //
3056                   if (moveSignaturesClef && mi) {
3057                         for (int staffIdx = 0; staffIdx < score->nstaves(); ++staffIdx) {
3058                               Measure* pm = mi->prevMeasure();
3059                               if (pm) {
3060                                     Segment* ps = pm->findSegment(SegmentType::Clef, tick);
3061                                     if (ps && ps->enabled()) {
3062                                           Element* pc = ps->element(staffIdx * VOICES);
3063                                           if (pc) {
3064                                                 pcl.push_back(toClef(pc));
3065                                                 undo(new RemoveElement(pc));
3066                                                 if (ps->empty())
3067                                                       undoRemoveElement(ps);
3068                                                 }
3069                                           }
3070                                     }
3071                               for (Segment* s = mi->first(); s && s->rtick().isZero(); s = s->next()) {
3072                                     if (!s->enabled())
3073                                           continue;
3074                                     Element* e = s->element(staffIdx * VOICES);
3075                                     if (!e || e->generated())
3076                                           continue;
3077                                     Element* ee = 0;
3078                                     if (e->isKeySig()) {
3079                                           KeySig* ks = toKeySig(e);
3080                                           ksl.push_back(ks);
3081                                           ee = e;
3082                                           }
3083                                     else if (e->isTimeSig()) {
3084                                           TimeSig* ts = toTimeSig(e);
3085                                           tsl.push_back(ts);
3086                                           ee = e;
3087                                           }
3088                                     if (tick.isZero() && e->isClef()) {
3089                                           Clef* clef = toClef(e);
3090                                           cl.push_back(clef);
3091                                           ee = e;
3092                                           }
3093                                     if (ee) {
3094                                           undo(new RemoveElement(ee));
3095                                           if (s->empty())
3096                                                 undoRemoveElement(s);
3097                                           }
3098                                     }
3099                               }
3100                         }
3101 
3102 
3103                   //
3104                   // move clef, time, key signatrues
3105                   //
3106                   for (TimeSig* ts : tsl) {
3107                         TimeSig* nts = new TimeSig(*ts);
3108                         Segment* s   = m->undoGetSegmentR(SegmentType::TimeSig, Fraction(0,1));
3109                         nts->setParent(s);
3110                         undoAddElement(nts);
3111                         }
3112                   for (KeySig* ks : ksl) {
3113                         KeySig* nks = new KeySig(*ks);
3114                         Segment* s  = m->undoGetSegmentR(SegmentType::KeySig, Fraction(0,1));
3115                         nks->setParent(s);
3116                         undoAddElement(nks);
3117                         }
3118                   for (Clef* clef : cl) {
3119                         Clef* nClef = new Clef(*clef);
3120                         Segment* s  = m->undoGetSegmentR(SegmentType::HeaderClef, Fraction(0,1));
3121                         nClef->setParent(s);
3122                         undoAddElement(nClef);
3123                         }
3124                   Measure* pm = m->prevMeasure();
3125                   for (Clef* clef : pcl) {
3126                         Clef* nClef = new Clef(*clef);
3127                         Segment* s  = pm->undoGetSegment(SegmentType::Clef, tick);
3128                         nClef->setParent(s);
3129                         undoAddElement(nClef);
3130                         }
3131                   }
3132             else {
3133                   // a frame, not a measure
3134                   if (score->isMaster())
3135                         rmb = mb;
3136                   else if (rmb && mb != rmb) {
3137                         mb->linkTo(rmb);
3138                         if (rmb->isTBox())
3139                               toTBox(mb)->text()->linkTo(toTBox(rmb)->text());
3140                         }
3141                   }
3142             }
3143 
3144       undoInsertTime(tick, ticks);
3145 
3146       if (om && !createEmptyMeasures) {
3147             //
3148             // fill measure with rest
3149             //
3150             Score* score = om->score();
3151 
3152             // add rest to all staves and to all the staves linked to it
3153             for (int staffIdx = 0; staffIdx < score->nstaves(); ++staffIdx) {
3154                   int track = staffIdx * VOICES;
3155                   Rest* rest = new Rest(score, TDuration(TDuration::DurationType::V_MEASURE));
3156                   Fraction timeStretch(score->staff(staffIdx)->timeStretch(om->tick()));
3157                   rest->setTicks(om->ticks() * timeStretch);
3158                   rest->setTrack(track);
3159                   score->undoAddCR(rest, om, tick);
3160                   }
3161             }
3162       deselectAll();
3163       }
3164 
3165 //---------------------------------------------------------
3166 //   checkSpanner
3167 //    check if spanners are still valid as anchors may
3168 //    have changed or be removed.
3169 //    Spanners need to have a start anchor. Slurs need a
3170 //    start and end anchor.
3171 //---------------------------------------------------------
3172 
checkSpanner(const Fraction & startTick,const Fraction & endTick)3173 void Score::checkSpanner(const Fraction& startTick, const Fraction& endTick)
3174       {
3175       QList<Spanner*> sl;     // spanners to remove
3176       QList<Spanner*> sl2;    // spanners to shorten
3177       auto spanners = _spanner.findOverlapping(startTick.ticks(), endTick.ticks());
3178 
3179       // DEBUG: check all spanner
3180       //        there may be spanners outside of score bc. some measures were deleted
3181 
3182       Fraction lastTick = lastMeasure()->endTick();
3183 
3184       for (auto i : _spanner.map()) {
3185             Spanner* s = i.second;
3186 
3187             if (s->isSlur()) {
3188                   Segment* seg = tick2segmentMM(s->tick(), false, SegmentType::ChordRest);
3189                   if (!seg || !seg->element(s->track()))
3190                         sl.append(s);
3191                   else {
3192                         seg = tick2segmentMM(s->tick2(), false, SegmentType::ChordRest);
3193                         if (!seg || !seg->element(s->track2()))
3194                               sl.append(s);
3195                         }
3196                   }
3197             else {
3198                   // remove spanner if there is no start element
3199                   s->computeStartElement();
3200                   if (!s->startElement()) {
3201                         sl.append(s);
3202                         qDebug("checkSpanner::remove (3)");
3203                         }
3204                   else {
3205                         if (s->tick2() > lastTick)
3206                               sl2.append(s);    //s->undoChangeProperty(Pid::SPANNER_TICKS, lastTick - s->tick());
3207                         else
3208                               s->computeEndElement();
3209                         }
3210                   }
3211             }
3212       for (auto s : sl)       // actually remove scheduled spanners
3213             undo(new RemoveElement(s));
3214       for (auto s : sl2) {    // shorten spanners that extended past end of score
3215             undo(new ChangeProperty(s, Pid::SPANNER_TICKS, lastTick - s->tick()));
3216             s->computeEndElement();
3217             }
3218       }
3219 
3220 static constexpr SegmentType CR_TYPE = SegmentType::ChordRest;
3221 
3222 //---------------------------------------------------------
3223 //   checkTimeDelete
3224 //---------------------------------------------------------
3225 
checkTimeDelete(Segment * startSegment,Segment * endSegment)3226 bool Score::checkTimeDelete(Segment* startSegment, Segment* endSegment)
3227       {
3228       Measure* m = startSegment->measure();
3229       Measure* endMeasure;
3230 
3231       if (endSegment)
3232             endMeasure = endSegment->prev() ? endSegment->measure() : endSegment->measure()->prevMeasure();
3233       else
3234             endMeasure = lastMeasure();
3235 
3236       Fraction endTick = endSegment ? endSegment->tick() : endMeasure->endTick();
3237       Fraction tick = startSegment->tick();
3238       Fraction etick = (m == endMeasure ? endTick : m->endTick());
3239       bool canDeleteTime = true;
3240 
3241       while (canDeleteTime) {
3242             for (int track = 0; canDeleteTime && track < _staves.size() * VOICES; ++track) {
3243                   if (m->hasVoice(track)) {
3244                         Segment* fs = m->first(CR_TYPE);
3245                         for (Segment* s = fs; s; s = s->next(CR_TYPE)) {
3246                               if (s->element(track)) {
3247                                     ChordRest* cr       = toChordRest(s->element(track));
3248                                     Tuplet* t           = cr->tuplet();
3249                                     DurationElement* de = t ? toDurationElement(t) : toDurationElement(cr);
3250                                     Fraction f          = de->tick() + de->actualTicks();
3251                                     Fraction cetick     = f;
3252                                     if (cetick <= tick)
3253                                           continue;
3254                                     if (de->tick() >= etick)
3255                                           break;
3256                                     if (t && (t->tick() < tick || cetick > etick)) {
3257                                           canDeleteTime = false;
3258                                           break;
3259                                           }
3260                                     }
3261                               }
3262                         }
3263                   }
3264             if (m == endMeasure)
3265                   break;
3266             m     = endMeasure;
3267             tick  = m->tick();
3268             etick = endTick;
3269             }
3270       if (!canDeleteTime) {
3271             QMessageBox::information(0, "MuseScore",
3272                tr("Please select the complete tuplet and retry the command"),
3273                QMessageBox::Ok, QMessageBox::NoButton);
3274             return false;
3275             }
3276       return true;
3277       }
3278 
3279 //---------------------------------------------------------
3280 //   globalTimeDelete
3281 //---------------------------------------------------------
3282 
globalTimeDelete()3283 void Score::globalTimeDelete()
3284       {
3285       qDebug("not implemented");
3286       }
3287 
3288 //---------------------------------------------------------
3289 //   localTimeDelete
3290 //---------------------------------------------------------
3291 
localTimeDelete()3292 void Score::localTimeDelete()
3293       {
3294       Segment* startSegment;
3295       Segment* endSegment;
3296 
3297       if (selection().state() != SelState::RANGE) {
3298             Element* el = selection().element();
3299             if (!el)
3300                   return;
3301             ChordRest* cr = 0;
3302             if (el->isNote())
3303                   cr = toNote(el)->chord();
3304             else if (el->isChordRest())
3305                   cr = toChordRest(el);
3306             else
3307                   return;
3308             startSegment     = cr->segment();
3309             Fraction endTick = startSegment->tick() + cr->actualTicks();
3310             endSegment       = tick2measure(endTick)->findSegment(CR_TYPE, endTick);
3311             }
3312       else {
3313             startSegment = selection().startSegment();
3314             endSegment   = selection().endSegment();
3315             }
3316 
3317       if (!checkTimeDelete(startSegment, endSegment))
3318             return;
3319 
3320       MeasureBase* is = startSegment->measure();
3321       if (is->isMeasure() && toMeasure(is)->isMMRest())
3322             is = toMeasure(is)->mmRestFirst();
3323       MeasureBase* ie;
3324 
3325       if (endSegment)
3326             ie = endSegment->prev(SegmentType::ChordRest) ? endSegment->measure() : endSegment->measure()->prev();
3327       else
3328             ie = lastMeasure();
3329 
3330       Fraction endTick = endSegment ? endSegment->tick() : ie->endTick();
3331 
3332       for (;;) {
3333             if (is->tick() != startSegment->tick()) {
3334                   Fraction tick = startSegment->tick();
3335                   Fraction len;
3336                   if (ie == is)
3337                         len = endTick - tick;
3338                   else
3339                         len = is->endTick() - tick;
3340                   timeDelete(toMeasure(is), startSegment, len);
3341                   if (is == ie)
3342                         break;
3343                   is = is->next();
3344                   }
3345             endTick = endSegment ? endSegment->tick() : ie->endTick();
3346             if (ie->endTick() != endTick) {
3347                   Fraction len = endTick - ie->tick();
3348                   timeDelete(toMeasure(ie), toMeasure(ie)->first(), len);
3349                   if (is == ie)
3350                         break;
3351                   ie = ie->prev();
3352                   }
3353             deleteMeasures(is, ie);
3354             break;
3355             };
3356 
3357       if (noteEntryMode()) {
3358             Segment* currentSegment = endSegment;
3359             ChordRest* cr = nullptr;
3360             if (!currentSegment && lastMeasureMM()) {
3361                   // deleted to end of score - get last cr on current track
3362                   currentSegment = lastMeasureMM()->last();
3363                   if (currentSegment) {
3364                         cr = currentSegment->nextChordRest(_is.track(), true);
3365                         if (cr)
3366                               currentSegment = cr->segment();
3367                         }
3368                   }
3369             if (!currentSegment) {
3370                   // no cr found - append a new measure
3371                   appendMeasures(1);
3372                   currentSegment = lastMeasureMM()->first(SegmentType::ChordRest);
3373                   }
3374             _is.setSegment(currentSegment);
3375             cr = _is.cr();
3376             if (cr) {
3377                   if (cr->isChord())
3378                         select(toChord(cr)->upNote(), SelectType::SINGLE);
3379                   else
3380                         select(cr, SelectType::SINGLE);
3381                   }
3382             else {
3383                   // could not find cr to select,
3384                   // may be that there is a "hole" in the current track
3385                   deselectAll();
3386                   }
3387             }
3388       else {
3389             deselectAll();
3390             }
3391       }
3392 
3393 //---------------------------------------------------------
3394 //   timeDelete
3395 //---------------------------------------------------------
3396 
timeDelete(Measure * m,Segment * startSegment,const Fraction & f)3397 void Score::timeDelete(Measure* m, Segment* startSegment, const Fraction& f)
3398       {
3399       if (f.isZero())
3400             return;
3401 
3402       const Fraction tick  = startSegment->rtick();
3403       const Fraction len   = f;
3404       const Fraction etick = tick + len;
3405 
3406       Segment* fs = m->first(CR_TYPE);
3407 
3408       for (int track = 0; track < _staves.size() * VOICES; ++track) {
3409             if (m->hasVoice(track)) {
3410                   for (Segment* s = fs; s; s = s->next(CR_TYPE)) {
3411                         if (s->element(track)) {
3412                               ChordRest* cr   = toChordRest(s->element(track));
3413                               Fraction cetick = cr->rtick() + cr->actualTicks();
3414 
3415                               if (cetick <= tick)
3416                                     continue;
3417                               if (s->rtick() >= etick)
3418                                     break;
3419 
3420                               if (cr->isFullMeasureRest()) {
3421                                     if (cr->rtick() >= tick) {
3422                                           // Move full-measure rest from the deleted area
3423                                           undoRemoveElement(cr);
3424                                           ChordRest* newCR = toChordRest(cr->clone());
3425                                           newCR->setTicks(cr->ticks() - f);
3426                                           undoAddCR(newCR, m, m->tick() + etick);
3427                                           }
3428                                     else
3429                                           cr->undoChangeProperty(Pid::DURATION, cr->ticks() - f);
3430                                     }
3431                               // inside deleted area
3432                               else if (s->rtick() >= tick && cetick <= etick) {
3433                                     // inside
3434                                     undoRemoveElement(cr);
3435                                     }
3436                               else if (s->rtick() >= tick) {
3437                                     // running out
3438                                     Fraction ff = cetick - etick;
3439                                     undoRemoveElement(cr);
3440                                     createCRSequence(ff, cr, tick + len);
3441                                     }
3442                               else if (s->rtick() < tick && cetick <= etick) {
3443                                     // running in
3444                                     Fraction f1 = tick - s->rtick();
3445                                     changeCRlen(cr, f1, false);
3446                                     }
3447                               else {
3448                                     // running in/out
3449                                     Fraction f1 = cr->ticks() - f;
3450                                     changeCRlen(cr, f1, false);
3451                                     }
3452                               }
3453                         }
3454                   }
3455             }
3456       const Fraction abstick = startSegment->tick();
3457       undoInsertTime(abstick, -len);
3458 
3459       std::vector<Segment*> emptySegments;
3460 
3461       for (Score* score : masterScore()->scoreList()) {
3462             Measure* localMeasure = score->tick2measure(abstick);
3463 
3464             undo(new InsertTime(score, abstick, -len));
3465 
3466             Fraction updatedTick = tick;
3467             for (Segment* s = localMeasure->first(CR_TYPE); s; s = s->next()) {
3468                   if (s->rtick() < etick || s->rtick() == updatedTick)
3469                         continue;
3470 
3471                   s->undoChangeProperty(Pid::TICK, updatedTick);
3472                   updatedTick += s->ticks();
3473 
3474                   if (score->isMaster()) {
3475                         if (s->isChordRestType() && !s->hasElements())
3476                               emptySegments.push_back(s);
3477                         }
3478                   }
3479 
3480             undo(new ChangeMeasureLen(localMeasure, localMeasure->ticks() - f));
3481             }
3482 
3483       for (Segment* s : emptySegments) {
3484             if (Segment* ns = s->next(CR_TYPE)) {
3485                   // Move annotations from the empty segment.
3486                   // TODO: do we need to preserve annotations at all?
3487                   // Maybe only some types (Tempo etc.)?
3488                   for (Element* a : s->annotations()) {
3489                         Element* a1 = a->clone();
3490                         a1->setParent(ns);
3491                         undoRemoveElement(a);
3492                         undoAddElement(a1);
3493                         }
3494                   }
3495             }
3496       }
3497 
3498 //---------------------------------------------------------
3499 //   cloneVoice
3500 //---------------------------------------------------------
3501 
cloneVoice(int strack,int dtrack,Segment * sf,const Fraction & lTick,bool link,bool spanner)3502 void Score::cloneVoice(int strack, int dtrack, Segment* sf, const Fraction& lTick, bool link, bool spanner)
3503       {
3504       Fraction start = sf->tick();
3505       TieMap  tieMap;
3506       TupletMap tupletMap;    // tuplets cannot cross measure boundaries
3507       Score* score = sf->score();
3508       Tremolo* tremolo = 0;
3509 
3510       for (Segment* oseg = sf; oseg && oseg->tick() < lTick; oseg = oseg->next1()) {
3511             Segment* ns = 0;        //create segment later, on demand
3512             Measure* dm = tick2measure(oseg->tick());
3513 
3514             Element* oe = oseg->element(strack);
3515 
3516             if (oe && !oe->generated() && oe->isChordRest()) {
3517                   Element* ne;
3518                   //does a linked clone to create just this element
3519                   //otherwise element will be add in every linked stave
3520                   if (link)
3521                         ne = oe->linkedClone();
3522                   else
3523                         ne = oe->clone();
3524                   ne->setTrack(dtrack);
3525 
3526                   //Don't clone gaps to a first voice
3527                   if (!(ne->track() % VOICES) && ne->isRest())
3528                         toRest(ne)->setGap(false);
3529 
3530                   ne->setScore(this);
3531                   ChordRest* ocr = toChordRest(oe);
3532                   ChordRest* ncr = toChordRest(ne);
3533 
3534                   //Handle beams
3535                   if (ocr->beam() && !ocr->beam()->empty() && ocr->beam()->elements().front() == ocr) {
3536                         Beam* nb = ocr->beam()->clone();
3537                         nb->clear();
3538                         nb->setTrack(dtrack);
3539                         nb->setScore(this);
3540                         nb->add(ncr);
3541                         ncr->setBeam(nb);
3542                         }
3543 
3544                   // clone Tuplets
3545                   Tuplet* ot = ocr->tuplet();
3546                   if (ot) {
3547                         ot->setTrack(strack);
3548                         Tuplet* nt = tupletMap.findNew(ot);
3549                         if (nt == 0) {
3550                               if (link)
3551                                     nt = toTuplet(ot->linkedClone());
3552                               else
3553                                     nt = toTuplet(ot->clone());
3554                               nt->setTrack(dtrack);
3555                               nt->setParent(dm);
3556                               tupletMap.add(ot, nt);
3557 
3558                               Tuplet* nt1 = nt;
3559                               while (ot->tuplet()) {
3560                                     Tuplet* nt2 = tupletMap.findNew(ot->tuplet());
3561                                     if (nt2 == 0) {
3562                                           if (link)
3563                                                 nt2 = toTuplet(ot->tuplet()->linkedClone());
3564                                           else
3565                                                 nt2 = toTuplet(ot->tuplet()->clone());
3566                                           nt2->setTrack(dtrack);
3567                                           nt2->setParent(dm);
3568                                           tupletMap.add(ot->tuplet(), nt2);
3569                                           }
3570                                     nt2->add(nt1);
3571                                     nt1->setTuplet(nt2);
3572                                     ot = ot->tuplet();
3573                                     nt1 = nt2;
3574                                     }
3575                               }
3576                         nt->add(ncr);
3577                         ncr->setTuplet(nt);
3578                         }
3579 
3580                   // clone additional settings
3581                   if (oe->isChordRest()) {
3582                         if (oe->isRest()) {
3583                               Rest* ore = toRest(ocr);
3584                               // If we would clone a full measure rest just don't clone this rest
3585                               if (ore->isFullMeasureRest() && (dtrack % VOICES)) {
3586                                     continue;
3587                                     }
3588                               }
3589 
3590                         if (oe->isChord()) {
3591                               Chord* och = toChord(ocr);
3592                               Chord* nch = toChord(ncr);
3593 
3594                               size_t n = och->notes().size();
3595                               for (size_t i = 0; i < n; ++i) {
3596                                     Note* on = och->notes().at(i);
3597                                     Note* nn = nch->notes().at(i);
3598                                     int idx = track2staff(dtrack);
3599                                     Fraction tick = oseg->tick();
3600                                     Interval v = staff(idx) ? staff(idx)->part()->instrument(tick)->transpose() : Interval();
3601                                     nn->setTpc1(on->tpc1());
3602                                     if (v.isZero())
3603                                           nn->setTpc2(on->tpc1());
3604                                     else {
3605                                           v.flip();
3606                                           nn->setTpc2(Ms::transposeTpc(nn->tpc1(), v, true));
3607                                           }
3608 
3609                                     if (on->tieFor()) {
3610                                           Tie* tie;
3611                                           if (link)
3612                                                 tie = toTie(on->tieFor()->linkedClone());
3613                                           else
3614                                                 tie = toTie(on->tieFor()->clone());
3615                                           tie->setScore(this);
3616                                           nn->setTieFor(tie);
3617                                           tie->setStartNote(nn);
3618                                           tie->setTrack(nn->track());
3619                                           tie->setEndNote(nn);
3620                                           tieMap.add(on->tieFor(), tie);
3621                                           }
3622                                     if (on->tieBack()) {
3623                                           Tie* tie = tieMap.findNew(on->tieBack());
3624                                           if (tie) {
3625                                                 nn->setTieBack(tie);
3626                                                 tie->setEndNote(nn);
3627                                                 }
3628                                           else {
3629                                                 qDebug("cloneVoices: cannot find tie");
3630                                                 }
3631                                           }
3632                                     // add back spanners (going back from end to start spanner element
3633                                     // makes sure the 'other' spanner anchor element is already set up)
3634                                     // 'on' is the old spanner end note and 'nn' is the new spanner end note
3635                                     for (Spanner* oldSp : on->spannerBack()) {
3636                                           Note* newStart = Spanner::startElementFromSpanner(oldSp, nn);
3637                                           if (newStart) {
3638                                                 Spanner* newSp;
3639                                                 if (link)
3640                                                       newSp = toSpanner(oldSp->linkedClone());
3641                                                 else
3642                                                       newSp = toSpanner(oldSp->clone());
3643                                                 newSp->setNoteSpan(newStart, nn);
3644                                                 addElement(newSp);
3645                                                 }
3646                                           else {
3647                                                 qDebug("cloneVoices: cannot find spanner start note");
3648                                                 }
3649                                           }
3650                                     }
3651                               // two note tremolo
3652                               if (och->tremolo() && och->tremolo()->twoNotes()) {
3653                                    if (och == och->tremolo()->chord1()) {
3654                                           if (tremolo)
3655                                                 qDebug("unconnected two note tremolo");
3656                                           if (link)
3657                                                 tremolo = toTremolo(och->tremolo()->linkedClone());
3658                                           else
3659                                                 tremolo = toTremolo(och->tremolo()->clone());
3660                                           tremolo->setScore(nch->score());
3661                                           tremolo->setParent(nch);
3662                                           tremolo->setTrack(nch->track());
3663                                           tremolo->setChords(nch, 0);
3664                                           nch->setTremolo(tremolo);
3665                                           }
3666                                     else if (och == och->tremolo()->chord2()) {
3667                                           if (!tremolo)
3668                                                 qDebug("first note for two note tremolo missing");
3669                                           else {
3670                                                 tremolo->setChords(tremolo->chord1(), nch);
3671                                                 nch->setTremolo(tremolo);
3672                                                 }
3673                                           }
3674                                     else
3675                                           qDebug("inconsistent two note tremolo");
3676                                     }
3677                               }
3678 
3679                         // Add element (link -> just in this measure)
3680                         if (link) {
3681                               if (!ns)
3682                                     ns = dm->getSegment(oseg->segmentType(), oseg->tick());
3683                               ns->add(ne);
3684                               }
3685                         else {
3686                               undoAddCR(toChordRest(ne), dm, oseg->tick());
3687                               }
3688                         }
3689                   }
3690             Segment* tst = dm->segments().firstCRSegment();
3691             if (strack % VOICES && !(dtrack % VOICES) && (!tst || (!tst->element(dtrack)))) {
3692                   Rest* rest = new Rest(this);
3693                   rest->setTicks(dm->ticks());
3694                   rest->setDurationType(TDuration::DurationType::V_MEASURE);
3695                   rest->setTrack(dtrack);
3696                   if (link) {
3697                         Segment* segment = dm->getSegment(SegmentType::ChordRest, dm->tick());
3698                         segment->add(rest);
3699                         }
3700                   else
3701                         undoAddCR(toChordRest(rest), dm, dm->tick());
3702                   }
3703             }
3704 
3705       if (spanner) {
3706             // Find and add corresponding slurs
3707             auto spanners = score->spannerMap().findOverlapping(start.ticks(), lTick.ticks());
3708             for (auto i = spanners.begin(); i < spanners.end(); i++) {
3709                   Spanner* sp      = i->value;
3710                   Fraction spStart = sp->tick();
3711                   int track        = sp->track();
3712                   int track2       = sp->track2();
3713                   Fraction spEnd   = spStart + sp->ticks();
3714 
3715                   if (sp->isSlur() && (spStart >= start && spEnd < lTick)) {
3716                         if (track == strack && track2 == strack){
3717                               Spanner* ns = toSpanner(link ? sp->linkedClone() : sp->clone());
3718 
3719                               ns->setScore(this);
3720                               ns->setParent(0);
3721                               ns->setTrack(dtrack);
3722                               ns->setTrack2(dtrack);
3723 
3724                               // set start/end element for slur
3725                               ChordRest* cr1 = sp->startCR();
3726                               ChordRest* cr2 = sp->endCR();
3727 
3728                               ns->setStartElement(0);
3729                               ns->setEndElement(0);
3730                               if (cr1 && cr1->links()) {
3731                                     for (ScoreElement* e : *cr1->links()) {
3732                                           ChordRest* cr = toChordRest(e);
3733                                           if (cr == cr1)
3734                                                 continue;
3735                                           if ((cr->score() == this) && (cr->tick() == ns->tick()) && cr->track() == dtrack) {
3736                                                 ns->setStartElement(cr);
3737                                                 break;
3738                                                 }
3739                                           }
3740                                     }
3741                               if (cr2 && cr2->links()) {
3742                                     for (ScoreElement* e : *cr2->links()) {
3743                                           ChordRest* cr = toChordRest(e);
3744                                           if (cr == cr2)
3745                                                 continue;
3746                                           if ((cr->score() == this) && (cr->tick() == ns->tick2()) && cr->track() == dtrack) {
3747                                                 ns->setEndElement(cr);
3748                                                 break;
3749                                                 }
3750                                           }
3751                                     }
3752                               undo(new AddElement(ns));
3753                               }
3754                         }
3755                   }
3756             }
3757 
3758       //Layout
3759 //TODO ??      doLayoutRange(start, lTick);
3760       }
3761 
3762 //---------------------------------------------------------
3763 //   undoPropertyChanged
3764 //    return true if an property was actually changed
3765 //---------------------------------------------------------
3766 
undoPropertyChanged(Element * e,Pid t,const QVariant & st,PropertyFlags ps)3767 bool Score::undoPropertyChanged(Element* e, Pid t, const QVariant& st, PropertyFlags ps)
3768       {
3769       bool changed = false;
3770 
3771       if (propertyLink(t) && e->links()) {
3772             for (ScoreElement* ee : *e->links()) {
3773                   if (ee == e) {
3774                         if (ee->getProperty(t) != st) {
3775                               undoStack()->push1(new ChangeProperty(ee, t, st, ps));
3776                               changed = true;
3777                               }
3778                         }
3779                   else {
3780                         // property in linked element has not changed yet
3781                         // push() calls redo() to change it
3782                         if (ee->getProperty(t) != e->getProperty(t)) {
3783                               undoStack()->push(new ChangeProperty(ee, t, e->getProperty(t), ps), 0);
3784                               changed = true;
3785                               }
3786                         }
3787                   }
3788             }
3789       else {
3790             PropertyFlags po = e->propertyFlags(t);
3791             if ((e->getProperty(t) != st) || (ps != po)) {
3792                   e->setPropertyFlags(t, ps);
3793                   undoStack()->push1(new ChangeProperty(e, t, st, po));
3794                   changed = true;
3795                   }
3796             }
3797       return changed;
3798       }
3799 
undoPropertyChanged(ScoreElement * e,Pid t,const QVariant & st,PropertyFlags ps)3800 void Score::undoPropertyChanged(ScoreElement* e, Pid t, const QVariant& st, PropertyFlags ps)
3801       {
3802       if (e->getProperty(t) != st)
3803             undoStack()->push1(new ChangeProperty(e, t, st, ps));
3804       }
3805 
3806 //---------------------------------------------------------
3807 //   undoChangeStyleVal
3808 //---------------------------------------------------------
3809 
undoChangeStyleVal(Sid idx,const QVariant & v)3810 void Score::undoChangeStyleVal(Sid idx, const QVariant& v)
3811       {
3812       undo(new ChangeStyleVal(this, idx, v));
3813       }
3814 
3815 //---------------------------------------------------------
3816 //   undoChangePageNumberOffset
3817 //---------------------------------------------------------
3818 
undoChangePageNumberOffset(int po)3819 void Score::undoChangePageNumberOffset(int po)
3820       {
3821       undo(new ChangePageNumberOffset(this, po));
3822       }
3823 
3824 //---------------------------------------------------------
3825 //   undoChangeElement
3826 //---------------------------------------------------------
3827 
undoChangeElement(Element * oldElement,Element * newElement)3828 void Score::undoChangeElement(Element* oldElement, Element* newElement)
3829       {
3830       if (!oldElement)
3831             undoAddElement(newElement);
3832       else
3833             undo(new ChangeElement(oldElement, newElement));
3834       }
3835 
3836 //---------------------------------------------------------
3837 //   undoChangePitch
3838 //---------------------------------------------------------
3839 
undoChangePitch(Note * note,int pitch,int tpc1,int tpc2)3840 void Score::undoChangePitch(Note* note, int pitch, int tpc1, int tpc2)
3841       {
3842       for (ScoreElement* e : note->linkList()) {
3843             Note* n = toNote(e);
3844             undoStack()->push(new ChangePitch(n, pitch, tpc1, tpc2), 0);
3845             }
3846       }
3847 
3848 //---------------------------------------------------------
3849 //   undoChangeFretting
3850 //
3851 //    To use with tablatures to force a specific note fretting;
3852 //    Pitch, string and fret must be changed all together; otherwise,
3853 //    if they are not consistent among themselves, the refretting algorithm may re-assign
3854 //    fret and string numbers for (potentially) all the notes of all the chords of a segment.
3855 //---------------------------------------------------------
3856 
undoChangeFretting(Note * note,int pitch,int string,int fret,int tpc1,int tpc2)3857 void Score::undoChangeFretting(Note* note, int pitch, int string, int fret, int tpc1, int tpc2)
3858       {
3859       const LinkedElements* l = note->links();
3860       if (l) {
3861             for (ScoreElement* e : *l) {
3862                   Note* n = toNote(e);
3863                   undo(new ChangeFretting(n, pitch, string, fret, tpc1, tpc2));
3864                   }
3865             }
3866       else
3867             undo(new ChangeFretting(note, pitch, string, fret, tpc1, tpc2));
3868       }
3869 
3870 //---------------------------------------------------------
3871 //   undoChangeKeySig
3872 //---------------------------------------------------------
3873 
undoChangeKeySig(Staff * ostaff,const Fraction & tick,KeySigEvent key)3874 void Score::undoChangeKeySig(Staff* ostaff, const Fraction& tick, KeySigEvent key)
3875       {
3876       KeySig* lks = 0;
3877 
3878       for (Staff* staff : ostaff->staffList()) {
3879             if (staff->isDrumStaff(tick))
3880                   continue;
3881 
3882             Score* score = staff->score();
3883             Measure* measure = score->tick2measure(tick);
3884             KeySigEvent currentKeySigEvent = staff->keySigEvent(tick);
3885             if (!measure) {
3886                   qWarning("measure for tick %d not found!", tick.ticks());
3887                   continue;
3888                   }
3889             Segment* s   = measure->undoGetSegment(SegmentType::KeySig, tick);
3890 
3891             int staffIdx = staff->idx();
3892             int track    = staffIdx * VOICES;
3893             KeySig* ks   = toKeySig(s->element(track));
3894 
3895             Interval interval = staff->part()->instrument(tick)->transpose();
3896             KeySigEvent nkey  = key;
3897             bool concertPitch = score->styleB(Sid::concertPitch);
3898 
3899             if (interval.chromatic && !concertPitch && !nkey.custom() && !nkey.isAtonal()) {
3900                   interval.flip();
3901                   nkey.setKey(transposeKey(key.key(), interval, staff->part()->preferSharpFlat()));
3902                   }
3903 
3904             updateInstrumentChangeTranspositions(key, staff, tick);
3905             if (ks) {
3906                   ks->undoChangeProperty(Pid::GENERATED, false);
3907                   undo(new ChangeKeySig(ks, nkey, ks->showCourtesy()));
3908                   }
3909             else {
3910                   // do not create empty keysig unless custom or atonal
3911                   if (tick.isNotZero() || nkey.key() != Key::C || nkey.custom() || nkey.isAtonal()) {
3912                         KeySig* nks = new KeySig(score);
3913                         nks->setParent(s);
3914                         nks->setTrack(track);
3915                         nks->setKeySigEvent(nkey);
3916                         undo(new AddElement(nks));
3917                         if (lks)
3918                               undo(new Link(lks, nks));
3919                         else
3920                               lks = nks;
3921                         }
3922                   }
3923             }
3924       }
3925 
updateInstrumentChangeTranspositions(KeySigEvent & key,Staff * staff,const Fraction & tick)3926 void Score::updateInstrumentChangeTranspositions(KeySigEvent& key, Staff* staff, const Fraction& tick)
3927       {
3928       if (!key.forInstrumentChange()) {
3929             KeyList* kl = staff->keyList();
3930             int nextTick = kl->nextKeyTick(tick.ticks());
3931 
3932             while (nextTick != -1) {
3933                   KeySigEvent e = kl->key(nextTick);
3934                   if (e.forInstrumentChange()) {
3935                         Measure* m = tick2measure(Fraction::fromTicks(nextTick));
3936                         Segment* s = m->tick2segment(Fraction::fromTicks(nextTick), SegmentType::KeySig);
3937                         int track = staff->idx() * VOICES;
3938                         KeySig* keySig = toKeySig(s->element(track));
3939                         if (key.isAtonal() && !e.isAtonal()) {
3940                               e.setMode(KeyMode::NONE);
3941                               e.setKey(Key::C);
3942                               }
3943                         else {
3944                               e.setMode(key.mode());
3945                               Interval transposeInterval = staff->part()->instrument(Fraction::fromTicks(nextTick))->transpose();
3946                               Interval previousTranspose = staff->part()->instrument(tick)->transpose();
3947                               transposeInterval.flip();
3948                               Key nkey = transposeKey(key.key(), transposeInterval);
3949                               nkey = transposeKey(nkey, previousTranspose);
3950                               e.setKey(nkey);
3951                               }
3952                         undo(new ChangeKeySig(keySig, e, keySig->showCourtesy()));
3953                         nextTick = kl->nextKeyTick(nextTick);
3954                         }
3955                   else
3956                         nextTick = -1;
3957                   }
3958             }
3959       }
3960 
3961 //---------------------------------------------------------
3962 //   undoChangeClef
3963 //    change clef if e is a clef
3964 //    else
3965 //    create a clef before element e
3966 //---------------------------------------------------------
3967 
undoChangeClef(Staff * ostaff,Element * e,ClefType ct,bool forInstrumentChange)3968 void Score::undoChangeClef(Staff* ostaff, Element* e, ClefType ct, bool forInstrumentChange)
3969       {
3970       bool moveClef = false;
3971       SegmentType st = SegmentType::Clef;
3972       if (e->isMeasure()) {
3973             if (toMeasure(e)->prevMeasure())
3974                   moveClef = true;
3975             else
3976                   st = SegmentType::HeaderClef;
3977             }
3978       else if (e->isClef()) {
3979             Clef* clef = toClef(e);
3980             if (clef->segment()->isHeaderClefType()) {
3981                   if (clef->measure()->prevMeasure())
3982                         moveClef = true;
3983                   else
3984                         st = SegmentType::HeaderClef;
3985                   }
3986             else if (clef->rtick() == clef->measure()->ticks())
3987                   moveClef = true;
3988             }
3989 
3990       Clef* gclef = 0;
3991       Fraction tick = e->tick();
3992       Fraction rtick = e->rtick();
3993       bool small = (st == SegmentType::Clef);
3994       for (Staff* staff : ostaff->staffList()) {
3995       //      if (staff->staffType(tick)->group() != ClefInfo::staffGroup(ct))
3996       //            continue;
3997 
3998             Score* score     = staff->score();
3999             Measure* measure = score->tick2measure(tick);
4000 
4001             if (!measure) {
4002                   qWarning("measure for tick %d not found!", tick.ticks());
4003                   continue;
4004                   }
4005 
4006             Segment* destSeg;
4007             Fraction rt;
4008             if (moveClef) {            // if at start of measure and there is a previous measure
4009                   measure = measure->prevMeasure();
4010                   rt      = measure->ticks();
4011                   }
4012             else
4013                   rt = rtick;
4014             destSeg = measure->undoGetSegmentR(st, rt);
4015 
4016             int staffIdx = staff->idx();
4017             int track    = staffIdx * VOICES;
4018             Clef* clef   = toClef(destSeg->element(track));
4019 
4020             if (clef) {
4021                   //
4022                   // for transposing instruments, differentiate
4023                   // clef type for concertPitch
4024                   //
4025                   Instrument* i = staff->part()->instrument(tick);
4026                   ClefType cp, tp;
4027                   if (i->transpose().isZero()) {
4028                         cp = ct;
4029                         tp = ct;
4030                         }
4031                   else {
4032                         bool concertPitch = clef->concertPitch();
4033                         if (concertPitch) {
4034                               cp = ct;
4035                               tp = clef->transposingClef();
4036                               }
4037                         else {
4038                               cp = clef->concertClef();
4039                               tp = ct;
4040                               }
4041                         }
4042                   clef->setGenerated(false);
4043                   score->undo(new ChangeClefType(clef, cp, tp));
4044                   Clef* oClef = clef->otherClef();
4045                   if (oClef && !(oClef->generated()))
4046                         score->undo(new ChangeClefType(oClef, cp, tp));
4047                   // change the clef in the mmRest if any
4048                   if (measure->hasMMRest()) {
4049                         Measure* mmMeasure = measure->mmRest();
4050                         Segment* mmDestSeg = mmMeasure->findSegment(SegmentType::Clef, tick);
4051                         if (mmDestSeg) {
4052                               Clef* mmClef = toClef(mmDestSeg->element(clef->track()));
4053                               if (mmClef)
4054                                     score->undo(new ChangeClefType(mmClef, cp, tp));
4055                               }
4056                         }
4057                   }
4058             else {
4059                   if (gclef) {
4060                         clef = toClef(gclef->linkedClone());
4061                         clef->setScore(score);
4062                         }
4063                   else {
4064                         clef = new Clef(score);
4065                         gclef = clef;
4066                         }
4067                   clef->setTrack(track);
4068                   clef->setClefType(ct);
4069                   clef->setParent(destSeg);
4070                   score->undo(new AddElement(clef));
4071                   clef->layout();
4072                   }
4073             if (forInstrumentChange) {
4074                   clef->setForInstrumentChange(true);
4075                   }
4076             clef->setSmall(small);
4077             }
4078       }
4079 
4080 //---------------------------------------------------------
4081 //   findLinkedVoiceElement
4082 //---------------------------------------------------------
4083 
findLinkedVoiceElement(Element * e,Staff * nstaff)4084 static Element* findLinkedVoiceElement(Element* e, Staff* nstaff)
4085       {
4086       Excerpt* se = e->score()->excerpt();
4087       Excerpt* de = nstaff->score()->excerpt();
4088       int strack = e->track();
4089       int dtrack = nstaff->idx() * VOICES + e->voice();
4090 
4091       if (se)
4092             strack = se->tracks().key(strack);
4093 
4094       if (de) {
4095             QList<int> l = de->tracks().values(strack);
4096             if (l.isEmpty()) {
4097                   // simply return the first linked element whose staff is equal to nstaff
4098                   for (ScoreElement* ee : e->linkList()) {
4099                         Element* el = toElement(ee);
4100                         if (el->staff() == nstaff)
4101                               return el;
4102                         }
4103                   return 0;
4104                   }
4105             for (int i : qAsConst(l)) {
4106                   if (nstaff->idx() * VOICES <= i && (nstaff->idx() + 1) * VOICES > i) {
4107                         dtrack = i;
4108                         break;
4109                         }
4110                   }
4111             }
4112 
4113       Score* score     = nstaff->score();
4114       Segment* segment = toSegment(e->parent());
4115       Measure* measure = segment->measure();
4116       Measure* m       = score->tick2measure(measure->tick());
4117       Segment* s       = m->findSegment(segment->segmentType(), segment->tick());
4118       return s->element(dtrack);
4119       }
4120 
4121 //---------------------------------------------------------
4122 //   findLinkedChord
4123 //---------------------------------------------------------
4124 
findLinkedChord(Chord * c,Staff * nstaff)4125 static Chord* findLinkedChord(Chord* c, Staff* nstaff)
4126       {
4127       Excerpt* se = c->score()->excerpt();
4128       Excerpt* de = nstaff->score()->excerpt();
4129       int strack = c->track();
4130       int dtrack = nstaff->idx() * VOICES + c->voice();
4131 
4132       if (se)
4133             strack = se->tracks().key(strack);
4134 
4135       if (de) {
4136             QList<int> l = de->tracks().values(strack);
4137             if (l.isEmpty()) {
4138                   // simply return the first linked chord whose staff is equal to nstaff
4139                   for (ScoreElement* ee : c->linkList()) {
4140                         Chord* ch = toChord(ee);
4141                         if (ch->staff() == nstaff)
4142                               return ch;
4143                         }
4144                   return 0;
4145                   }
4146             for (int i : qAsConst(l)) {
4147                   if (nstaff->idx() * VOICES <= i && (nstaff->idx() + 1) * VOICES > i) {
4148                         dtrack = i;
4149                         break;
4150                         }
4151                   }
4152             }
4153 
4154       Segment* s  = c->segment();
4155       Measure* nm = nstaff->score()->tick2measure(s->tick());
4156       Segment* ns = nm->findSegment(s->segmentType(), s->tick());
4157       Element* ne = ns->element(dtrack);
4158       if (!ne->isChord())
4159             return 0;
4160       Chord* nc = toChord(ne);
4161       if (c->isGrace()) {
4162             Chord* pc = toChord(c->parent());
4163             int index = 0;
4164             for (Chord* gc : pc->graceNotes()) {
4165                   if (c == gc)
4166                         break;
4167                   index++;
4168                   }
4169             if (index < nc->graceNotes().length())
4170                   nc = nc->graceNotes().at(index);
4171             }
4172       return nc;
4173       }
4174 
4175 //---------------------------------------------------------
4176 //   undoChangeChordRestLen
4177 //---------------------------------------------------------
4178 
undoChangeChordRestLen(ChordRest * cr,const TDuration & d)4179 void Score::undoChangeChordRestLen(ChordRest* cr, const TDuration& d)
4180       {
4181       auto sl = cr->staff()->staffList();
4182       for (Staff* staff : qAsConst(sl)) {
4183             ChordRest *ncr;
4184             if (cr->isGrace())
4185                   ncr = findLinkedChord(toChord(cr), staff);
4186             else
4187                   ncr = toChordRest(findLinkedVoiceElement(cr, staff));
4188             if (!ncr)
4189                   continue;
4190             ncr->undoChangeProperty(Pid::DURATION_TYPE, QVariant::fromValue(d));
4191             ncr->undoChangeProperty(Pid::DURATION, QVariant::fromValue(d.fraction()));
4192             }
4193       }
4194 
4195 //---------------------------------------------------------
4196 //   undoTransposeHarmony
4197 //---------------------------------------------------------
4198 
undoTransposeHarmony(Harmony * h,int rootTpc,int baseTpc)4199 void Score::undoTransposeHarmony(Harmony* h, int rootTpc, int baseTpc)
4200       {
4201       undo(new TransposeHarmony(h, rootTpc, baseTpc));
4202       }
4203 
4204 //---------------------------------------------------------
4205 //   undoExchangeVoice
4206 //---------------------------------------------------------
4207 
undoExchangeVoice(Measure * measure,int srcVoice,int dstVoice,int srcStaff,int dstStaff)4208 void Score::undoExchangeVoice(Measure* measure, int srcVoice, int dstVoice, int srcStaff, int dstStaff)
4209       {
4210       Fraction tick = measure->tick();
4211 
4212       for (int staffIdx = srcStaff; staffIdx < dstStaff; ++staffIdx) {
4213             QSet<Staff*> staffList;
4214             for (Staff* s : staff(staffIdx)->staffList())
4215                   staffList.insert(s);
4216 
4217             int srcStaffTrack = staffIdx * VOICES;
4218             int srcTrack = srcStaffTrack + srcVoice;
4219             int dstTrack = srcStaffTrack + dstVoice;
4220             int trackDiff = dstVoice - srcVoice;
4221 
4222             //handle score and complete measures first
4223             undo(new ExchangeVoice(measure, srcTrack, dstTrack, staffIdx));
4224 
4225             for (Staff* st : staffList) {
4226                   int staffTrack = st->idx() * VOICES;
4227                   Measure* measure2 = st->score()->tick2measure(tick);
4228                   Excerpt* ex = st->score()->excerpt();
4229 
4230                   if (ex) {
4231                         QMultiMap<int, int> tracks = ex->tracks();
4232                         QList<int> srcTrackList = tracks.values(srcTrack);
4233                         QList<int> dstTrackList = tracks.values(dstTrack);
4234 
4235                         for (int srcTrack2 : qAsConst(srcTrackList)) {
4236                               // don't care about other linked staves
4237                               if (!(staffTrack <= srcTrack2) || !(srcTrack2 < staffTrack + VOICES))
4238                                     continue;
4239 
4240                               int tempTrack = tracks.key(srcTrack2);
4241                               QList<int> testTracks = tracks.values(tempTrack + trackDiff);
4242                               bool hasVoice = false;
4243                               for (int testTrack : qAsConst(testTracks)) {
4244                                     if (staffTrack <= testTrack && testTrack < staffTrack + VOICES && dstTrackList.contains(testTrack)) {
4245                                           hasVoice = true;
4246                                           // voice is simply exchangeable now (deal directly)
4247                                           undo(new ExchangeVoice(measure2, srcTrack2, testTrack, staffTrack / 4));
4248                                           }
4249                                     }
4250 
4251                               // only source voice is in this staff
4252                               if (!hasVoice) {
4253                                     undo(new CloneVoice(measure->first(), measure2->endTick(), measure2->first(), tempTrack, srcTrack2, tempTrack + trackDiff));
4254                                     srcTrackList.removeOne(srcTrack2);
4255                                     }
4256                               }
4257 
4258                         for (int dstTrack2 : qAsConst(dstTrackList)) {
4259                               // don't care about other linked staves
4260                               if (!(staffTrack <= dstTrack2) || !(dstTrack2 < staffTrack + VOICES))
4261                                     continue;
4262 
4263                               int tempTrack = tracks.key(dstTrack2);
4264                               QList<int> testTracks = tracks.values(tempTrack - trackDiff);
4265                               bool hasVoice = false;
4266                               for (int testTrack : qAsConst(testTracks)) {
4267                                     if (staffTrack <= testTrack && testTrack < staffTrack + VOICES &&
4268                                         srcTrackList.contains(testTrack))
4269                                           hasVoice = true;
4270                                     }
4271 
4272                               // only destination voice is in this staff
4273                               if (!hasVoice) {
4274                                     undo(new CloneVoice(measure->first(), measure2->endTick(), measure2->first(), tempTrack, dstTrack2, tempTrack - trackDiff));
4275                                     dstTrackList.removeOne(dstTrack2);
4276                                     }
4277                               }
4278                         }
4279                   else if (srcStaffTrack != staffTrack) {
4280                         // linked staff in same score (all voices present can be assumed)
4281                         undo(new ExchangeVoice(measure2, staffTrack + srcVoice, staffTrack + dstVoice, st->idx()));
4282                         }
4283                   }
4284             }
4285 
4286       // make sure voice 0 is complete
4287 
4288       if (srcVoice == 0 || dstVoice == 0) {
4289             for (int staffIdx = srcStaff; staffIdx < dstStaff; ++staffIdx) {
4290                   // check for complete timeline of voice 0
4291                   Fraction ctick  = measure->tick();
4292                   int track = staffIdx * VOICES;
4293                   for (Segment* s = measure->first(SegmentType::ChordRest); s; s = s->next(SegmentType::ChordRest)) {
4294                         ChordRest* cr = toChordRest(s->element(track));
4295                         if (cr == 0)
4296                               continue;
4297                         if (cr->isRest()) {
4298                               Rest* r = toRest(cr);
4299                               if (r->isGap())
4300                                     r->undoChangeProperty(Pid::GAP, false);
4301                               }
4302                         if (ctick < s->tick())
4303                               setRest(ctick, track, s->tick() - ctick, false, 0);   // fill gap
4304                         ctick = s->tick() + cr->actualTicks();
4305                         }
4306                   Fraction etick = measure->endTick();
4307                   if (ctick < etick)
4308                         setRest(ctick, track, etick - ctick, false, 0);       // fill gap
4309                   }
4310             }
4311       }
4312 
4313 //---------------------------------------------------------
4314 //   undoRemovePart
4315 //---------------------------------------------------------
4316 
undoRemovePart(Part * part,int idx)4317 void Score::undoRemovePart(Part* part, int idx)
4318       {
4319       undo(new RemovePart(part, idx));
4320       }
4321 
4322 //---------------------------------------------------------
4323 //   undoInsertPart
4324 //---------------------------------------------------------
4325 
undoInsertPart(Part * part,int idx)4326 void Score::undoInsertPart(Part* part, int idx)
4327       {
4328       undo(new InsertPart(part, idx));
4329       }
4330 
4331 //---------------------------------------------------------
4332 //   undoRemoveStaff
4333 //    idx - index of staff in part
4334 //---------------------------------------------------------
4335 
undoRemoveStaff(Staff * staff)4336 void Score::undoRemoveStaff(Staff* staff)
4337       {
4338       const int idx = staff->idx();
4339       Q_ASSERT(idx >= 0);
4340 
4341       std::vector<Spanner*> toRemove;
4342       for (auto i = _spanner.cbegin(); i != _spanner.cend(); ++i) {
4343             Spanner* s = i->second;
4344             if (s->staffIdx() == idx && (idx != 0 || !s->systemFlag()))
4345                   toRemove.push_back(s);
4346             }
4347       for (Spanner* s : _unmanagedSpanner) {
4348             if (s->staffIdx() == idx && (idx != 0 || !s->systemFlag()))
4349                   toRemove.push_back(s);
4350             }
4351       for (Spanner* s : toRemove) {
4352             s->undoUnlink();
4353             undo(new RemoveElement(s));
4354             }
4355 
4356       //
4357       //    adjust measures
4358       //
4359       for (Measure* m = staff->score()->firstMeasure(); m; m = m->nextMeasure()) {
4360             m->cmdRemoveStaves(idx, idx+1);
4361             if (m->hasMMRest())
4362                   m->mmRest()->cmdRemoveStaves(idx, idx+1);
4363             }
4364 
4365       undo(new RemoveStaff(staff));
4366       }
4367 
4368 //---------------------------------------------------------
4369 //   undoInsertStaff
4370 //    idx - index of staff in part
4371 //---------------------------------------------------------
4372 
undoInsertStaff(Staff * staff,int ridx,bool createRests)4373 void Score::undoInsertStaff(Staff* staff, int ridx, bool createRests)
4374       {
4375       undo(new InsertStaff(staff, ridx));
4376       int idx = staffIdx(staff->part()) + ridx;
4377       for (Measure* m = firstMeasure(); m; m = m->nextMeasure()) {
4378             m->cmdAddStaves(idx, idx+1, createRests);
4379             if (m->hasMMRest())
4380                   m->mmRest()->cmdAddStaves(idx, idx+1, false);
4381             }
4382       // when newly adding an instrument,
4383       // this was already set when we created the staff
4384       // we don't have any better info at this point
4385       // and it dooesn't work to adjust bracket & barlines until all staves are added
4386       // TODO: adjust brackets only when appropriate
4387       //adjustBracketsIns(idx, idx+1);
4388       }
4389 
4390 //---------------------------------------------------------
4391 //   undoChangeInvisible
4392 //---------------------------------------------------------
4393 
undoChangeInvisible(Element * e,bool v)4394 void Score::undoChangeInvisible(Element* e, bool v)
4395       {
4396       e->undoChangeProperty(Pid::VISIBLE, v);
4397       e->setGenerated(false);
4398       }
4399 
4400 //---------------------------------------------------------
4401 //   undoAddElement
4402 //---------------------------------------------------------
4403 
undoAddElement(Element * element)4404 void Score::undoAddElement(Element* element)
4405       {
4406       QList<Staff* > staffList;
4407       Staff* ostaff = element->staff();
4408       int strack = -1;
4409       if (ostaff) {
4410             strack = ostaff->idx() * VOICES + element->track() % VOICES;
4411             if (ostaff->score()->excerpt() && !ostaff->score()->excerpt()->tracks().isEmpty() && strack > -1)
4412                   strack = ostaff->score()->excerpt()->tracks().key(strack, -1);
4413             }
4414 
4415       ElementType et = element->type();
4416 
4417       //
4418       // some elements are replicated for all parts regardless of
4419       // linking:
4420       //
4421 
4422       if ((et == ElementType::REHEARSAL_MARK)
4423          || (et == ElementType::SYSTEM_TEXT)
4424          || (et == ElementType::JUMP)
4425          || (et == ElementType::MARKER)
4426          || (et == ElementType::TEMPO_TEXT)
4427          || (et == ElementType::VOLTA)
4428          || ((et == ElementType::TEXTLINE) && element->systemFlag())
4429          ) {
4430             for (Score* s : scoreList())
4431                   staffList.append(s->staff(0));
4432 
4433             for (Staff* staff : staffList) {
4434                   Score* score  = staff->score();
4435                   int staffIdx  = staff->idx();
4436                   int ntrack    = staffIdx * VOICES;
4437                   Element* ne;
4438 
4439                   if (ostaff && staff->score() == ostaff->score())
4440                         ne = element;
4441                   else {
4442                         // only create linked volta/systemTextLine for first staff
4443                         if (((et == ElementType::VOLTA) || (et == ElementType::TEXTLINE)) && element->track() != 0)
4444                               continue;
4445                         ne = element->linkedClone();
4446                         ne->setScore(score);
4447                         ne->setSelected(false);
4448                         ne->setTrack(staffIdx * VOICES + element->voice());
4449                         }
4450 
4451                   if (et == ElementType::VOLTA || (et == ElementType::TEXTLINE)) {
4452                         Spanner* nsp = toSpanner(ne);
4453                         Spanner* sp = toSpanner(element);
4454                         int staffIdx1 = sp->track() / VOICES;
4455                         int staffIdx2 = sp->track2() / VOICES;
4456                         int diff = staffIdx2 - staffIdx1;
4457                         nsp->setTrack2((staffIdx + diff) * VOICES + (sp->track2() % VOICES));
4458                         undo(new AddElement(nsp));
4459                         }
4460                   else if (et == ElementType::MARKER || et == ElementType::JUMP) {
4461                         Measure* om = toMeasure(element->parent());
4462                         Measure* m  = score->tick2measure(om->tick());
4463                         ne->setTrack(element->track());
4464                         ne->setParent(m);
4465                         undo(new AddElement(ne));
4466                         }
4467                   else if (et == ElementType::MEASURE_NUMBER) {
4468                         toMeasure(element->parent())->undoChangeProperty(Pid::MEASURE_NUMBER_MODE, static_cast<int>(MeasureNumberMode::SHOW));
4469                         }
4470                   else {
4471                         Segment* segment  = toSegment(element->parent());
4472                         Fraction tick     = segment->tick();
4473                         Measure* m        = score->tick2measure(tick);
4474                         Segment* seg      = m->undoGetSegment(SegmentType::ChordRest, tick);
4475                         ne->setTrack(ntrack);
4476                         ne->setParent(seg);
4477                         undo(new AddElement(ne));
4478                         }
4479                   }
4480             return;
4481             }
4482 
4483       if (et == ElementType::FINGERING
4484          || (et == ElementType::IMAGE  && !element->parent()->isSegment())
4485          || (et == ElementType::SYMBOL && !element->parent()->isSegment())
4486          || et == ElementType::NOTE
4487          || et == ElementType::TEXT
4488          || et == ElementType::GLISSANDO
4489          || et == ElementType::BEND
4490          || (et == ElementType::CHORD && toChord(element)->isGrace())
4491             ) {
4492             Element* parent = element->parent();
4493             const LinkedElements* links = parent->links();
4494             // don't link part name
4495             if (et == ElementType::TEXT) {
4496                   Text* t = toText(element);
4497                   if (t->tid() == Tid::INSTRUMENT_EXCERPT)
4498                         links = 0;
4499                   }
4500             if (links == 0) {
4501                   undo(new AddElement(element));
4502                   return;
4503                   }
4504             for (ScoreElement* ee : *links) {
4505                   Element* e = static_cast<Element*>(ee);
4506                   Element* ne;
4507                   if (e == parent)
4508                         ne = element;
4509                   else {
4510                         if (element->isGlissando()) {    // and other spanners with Anchor::NOTE
4511                               Note* newEnd = Spanner::endElementFromSpanner(toGlissando(element), e);
4512                               if (newEnd) {
4513                                     ne = element->linkedClone();
4514                                     toSpanner(ne)->setNoteSpan(toNote(e), newEnd);
4515                                     }
4516                               else              //couldn't find suitable start note
4517                                     continue;
4518                               }
4519                         else if (element->isFingering()) {
4520                               bool tabFingering = e->staff()->staffType(e->tick())->showTabFingering();
4521                               if (e->staff()->isTabStaff(e->tick()) && !tabFingering)
4522                                     continue;
4523                               ne = element->linkedClone();
4524                               }
4525                         else
4526                               ne = element->linkedClone();
4527                         }
4528                   ne->setScore(e->score());
4529                   ne->setSelected(false);
4530                   ne->setParent(e);
4531                   undo(new AddElement(ne));
4532                   }
4533             return;
4534             }
4535 
4536       if (et == ElementType::LAYOUT_BREAK) {
4537             LayoutBreak* lb = toLayoutBreak(element);
4538             if (lb->layoutBreakType() == LayoutBreak::Type::SECTION) {
4539                   MeasureBase* m = lb->measure();
4540                   for (Score* s : scoreList()) {
4541                         if (s == lb->score())
4542                               undo(new AddElement(lb));
4543                         else {
4544                               Element* e = lb->linkedClone();
4545                               e->setScore(s);
4546                               Measure* nm = s->tick2measure(m->tick());
4547                               e->setParent(nm);
4548                               undo(new AddElement(e));
4549                               }
4550                         }
4551                   return;
4552                   }
4553             }
4554 
4555       if (ostaff == 0 || (
4556          et    != ElementType::ARTICULATION
4557          && et != ElementType::CHORDLINE
4558          && et != ElementType::LYRICS
4559          && et != ElementType::SLUR
4560          && et != ElementType::TIE
4561          && et != ElementType::NOTE
4562          && et != ElementType::INSTRUMENT_CHANGE
4563          && et != ElementType::HAIRPIN
4564          && et != ElementType::OTTAVA
4565          && et != ElementType::TRILL
4566          && et != ElementType::VIBRATO
4567          && et != ElementType::TEXTLINE
4568          && et != ElementType::PEDAL
4569          && et != ElementType::BREATH
4570          && et != ElementType::DYNAMIC
4571          && et != ElementType::STAFF_TEXT
4572          && et != ElementType::SYSTEM_TEXT
4573          && et != ElementType::STICKING
4574          && et != ElementType::TREMOLO
4575          && et != ElementType::ARPEGGIO
4576          && et != ElementType::SYMBOL
4577          && et != ElementType::IMAGE
4578          && et != ElementType::TREMOLOBAR
4579          && et != ElementType::FRET_DIAGRAM
4580          && et != ElementType::FERMATA
4581          && et != ElementType::HARMONY)
4582             ) {
4583             undo(new AddElement(element));
4584             return;
4585             }
4586 
4587       // For linked staves the length of staffList is always > 1 since the list contains the staff itself too!
4588       const bool linked = ostaff->staffList().length() > 1;
4589 
4590       for (Staff* staff : ostaff->staffList()) {
4591             Score* score = staff->score();
4592             int staffIdx = staff->idx();
4593 
4594             QList<int> tr;
4595             if (!staff->score()->excerpt()) {
4596                   // On masterScore.
4597                   int track = staff->idx() * VOICES + (strack % VOICES);
4598                   tr.append(track);
4599                   }
4600             else {
4601                   QMultiMap<int, int> mapping = staff->score()->excerpt()->tracks();
4602                   if (mapping.isEmpty()) {
4603                         // This can happen during reading the score and there is
4604                         // no Tracklist tag specified.
4605                         // TODO solve this in read302.cpp.
4606                         tr.append(strack);
4607                         }
4608                   else {
4609                         for (int track : mapping.values(strack)) {
4610                               // linkedPart : linked staves within same part/instrument.
4611                               // linkedScore: linked staves over different scores via excerpts.
4612                               const bool linkedPart  = linked && (staff != ostaff) && (staff->score() == ostaff->score());
4613                               const bool linkedScore = linked && (staff != ostaff) && (staff->score() != ostaff->score());
4614                               if (linkedPart && !linkedScore) {
4615                                     tr.append(staff->idx() * VOICES + mapping.value(track));
4616                                     }
4617                               else if (!linkedPart && linkedScore) {
4618                                     if ((track >> 2) != staffIdx)
4619                                           track += (staffIdx - (track >> 2)) * VOICES;
4620                                     tr.append(track);
4621                                     }
4622                               else {
4623                                     tr.append(track);
4624                                     }
4625                               }
4626                         }
4627                   }
4628 
4629 
4630             // Some elements in voice 1 of a staff should be copied to every track which has a linked voice in this staff
4631 
4632             if (tr.isEmpty() && (element->isSymbol()
4633                 || element->isImage()
4634                 || element->isTremoloBar()
4635                 || element->isDynamic()
4636                 || element->isStaffText()
4637                 || element->isSticking()
4638                 || element->isFretDiagram()
4639                 || element->isHarmony()
4640                 || element->isHairpin()
4641                 || element->isOttava()
4642                 || element->isTrill()
4643                 || element->isSlur()
4644                 || element->isVibrato()
4645                 || element->isTextLine()
4646                 || element->isPedal()
4647                 || element->isLyrics())) {
4648                   tr.append(staffIdx * VOICES);
4649                   }
4650 
4651             for (int ntrack : tr) {
4652                   Element* ne;
4653                   if (staff == ostaff)
4654                         ne = element;
4655                   else {
4656                         if (staff->rstaff() != ostaff->rstaff()) {
4657                               switch (element->type()) {
4658                                     // exclude certain element types except on corresponding staff in part
4659                                     // this should be same list excluded in cloneStaff()
4660                                     case ElementType::STAFF_TEXT:
4661                                     case ElementType::SYSTEM_TEXT:
4662                                     case ElementType::FRET_DIAGRAM:
4663                                     case ElementType::HARMONY:
4664                                     case ElementType::FIGURED_BASS:
4665                                     case ElementType::DYNAMIC:
4666                                     case ElementType::LYRICS:   // not normally segment-attached
4667                                           continue;
4668                                     default:
4669                                           break;
4670                                     }
4671                               }
4672                         ne = element->linkedClone();
4673                         ne->setScore(score);
4674                         ne->setSelected(false);
4675                         ne->setTrack(staffIdx * VOICES + element->voice());
4676 
4677                         if (ne->isFretDiagram()) {
4678                               FretDiagram* fd = toFretDiagram(ne);
4679                               Harmony* fdHarmony = fd->harmony();
4680                               if (fdHarmony) {
4681                                     fdHarmony->setScore(score);
4682                                     fdHarmony->setSelected(false);
4683                                     fdHarmony->setTrack(staffIdx * VOICES + element->voice());
4684                                     }
4685                               }
4686                         }
4687 
4688                   if (element->isArticulation()) {
4689                         Articulation* a  = toArticulation(element);
4690                         Segment* segment;
4691                         SegmentType st;
4692                         Measure* m;
4693                         Fraction tick;
4694                         if (a->parent()->isChordRest()) {
4695                               ChordRest* cr = a->chordRest();
4696                               segment       = cr->segment();
4697                               st            = SegmentType::ChordRest;
4698                               tick          = segment->tick();
4699                               m             = score->tick2measure(tick);
4700                               }
4701                         else {
4702                               segment  = toSegment(a->parent()->parent());
4703                               st       = SegmentType::EndBarLine;
4704                               tick     = segment->tick();
4705                               m        = score->tick2measure(tick);
4706                               if (m->tick() == tick)
4707                                     m = m->prevMeasure();
4708                               }
4709                         Segment* seg = m->findSegment(st, tick);
4710                         if (seg == 0) {
4711                               qWarning("undoAddSegment: segment not found");
4712                               break;
4713                               }
4714                         Articulation* na = toArticulation(ne);
4715                         na->setTrack(ntrack);
4716                         if (a->parent()->isChordRest()) {
4717                               ChordRest* cr = a->chordRest();
4718                               ChordRest* ncr;
4719                               if (cr->isGrace())
4720                                     ncr = findLinkedChord(toChord(cr), score->staff(staffIdx));
4721                               else
4722                                     ncr = toChordRest(seg->element(ntrack));
4723                               na->setParent(ncr);
4724                               }
4725                         else {
4726                               BarLine* bl = toBarLine(seg->element(ntrack));
4727                               na->setParent(bl);
4728                               }
4729                         undo(new AddElement(na));
4730                         }
4731                   else if (element->isChordLine() || element->isLyrics()) {
4732                         ChordRest* cr    = toChordRest(element->parent());
4733                         Segment* segment = cr->segment();
4734                         Fraction tick    = segment->tick();
4735                         Measure* m       = score->tick2measure(tick);
4736                         Segment* seg     = m->findSegment(SegmentType::ChordRest, tick);
4737                         if (seg == 0) {
4738                               qWarning("undoAddSegment: segment not found");
4739                               break;
4740                               }
4741                         ne->setTrack(ntrack);
4742                         ChordRest* ncr = toChordRest(seg->element(ntrack));
4743                         ne->setParent(ncr);
4744                         undo(new AddElement(ne));
4745                         }
4746                   //
4747                   // elements with Segment as parent
4748                   //
4749                   else if (element->isSymbol()
4750                      || element->isImage()
4751                      || element->isTremoloBar()
4752                      || element->isDynamic()
4753                      || element->isStaffText()
4754                      || element->isSticking()
4755                      || element->isFretDiagram()
4756                      || element->isFermata()
4757                      || element->isHarmony()) {
4758                         Segment* segment = element->parent()->isFretDiagram() ? toSegment(element->parent()->parent()) : toSegment(element->parent());
4759                         Fraction tick    = segment->tick();
4760                         Measure* m       = score->tick2measure(tick);
4761                         if ((segment->segmentType() == SegmentType::EndBarLine) && (m->tick() == tick))
4762                               m = m->prevMeasure();
4763                         Segment* seg     = m->undoGetSegment(segment->segmentType(), tick);
4764                         ne->setTrack(ntrack);
4765                         ne->setParent(seg);
4766 
4767                         // make harmony child of fret diagram if possible
4768                         if (ne->isHarmony()) {
4769                               for (Element* segel : segment->annotations()) {
4770                                     if (segel && segel->isFretDiagram() && segel->track() == ntrack) {
4771                                           segel->add(ne);
4772                                           break;
4773                                           }
4774                                     }
4775                               }
4776                         else if (ne->isFretDiagram()) {
4777                               // update track of child harmony
4778                               FretDiagram* fd = toFretDiagram(ne);
4779                               if (fd->harmony())
4780                                     fd->harmony()->setTrack(ntrack);
4781                               }
4782 
4783                         undo(new AddElement(ne));
4784                         // transpose harmony if necessary
4785                         if (element->isHarmony() && ne != element) {
4786                               Harmony* h = toHarmony(ne);
4787                               if (score->styleB(Sid::concertPitch) != element->score()->styleB(Sid::concertPitch)) {
4788                                     Part* partDest = h->part();
4789                                     Interval interval = partDest->instrument(tick)->transpose();
4790                                     if (!interval.isZero()) {
4791                                           if (!score->styleB(Sid::concertPitch))
4792                                                 interval.flip();
4793                                           int rootTpc = transposeTpc(h->rootTpc(), interval, true);
4794                                           int baseTpc = transposeTpc(h->baseTpc(), interval, true);
4795                                           score->undoTransposeHarmony(h, rootTpc, baseTpc);
4796                                           }
4797                                     }
4798                               }
4799                         }
4800                   else if (element->isSlur()
4801                      || element->isHairpin()
4802                      || element->isOttava()
4803                      || element->isTrill()
4804                      || element->isVibrato()
4805                      || element->isTextLine()
4806                      || element->isPedal()) {
4807                         Spanner* sp   = toSpanner(element);
4808                         Spanner* nsp  = toSpanner(ne);
4809                         int staffIdx1 = sp->track() / VOICES;
4810                         int tr2 = sp->effectiveTrack2();
4811                         int staffIdx2 = tr2 / VOICES;
4812                         int diff      = staffIdx2 - staffIdx1;
4813                         nsp->setTrack2((staffIdx + diff) * VOICES + (tr2 % VOICES));
4814                         nsp->setTrack(ntrack);
4815 
4816 #if 0 //whatdoesitdo?
4817                         QList<int> tl2;
4818                         if (staff->score()->excerpt() && element->isSlur()) {
4819                               nsp->setTrack(ntrack);
4820                                     tl2 = staff->score()->excerpt()->tracks().values(sp->track2());
4821                                     if (tl2.isEmpty()) {
4822                                           it++;
4823                                           continue;
4824                                           }
4825                                    nsp->setTrack2(tl2.at(it));
4826                               }
4827                         else if (!element->isSlur())
4828                               nsp->setTrack(ntrack & ~3);
4829 #endif
4830 
4831                         // determine start/end element for slurs
4832                         // this is only necessary if start/end element is
4833                         //   a grace note, otherwise the element can be set to zero
4834                         //   and will later be calculated from tick/track values
4835                         //
4836                         if (element->isSlur() && sp != nsp) {
4837                               if (sp->startElement()) {
4838                                     QList<ScoreElement*> sel = sp->startElement()->linkList();
4839                                     for (ScoreElement* ee : qAsConst(sel)) {
4840                                           Element* e = static_cast<Element*>(ee);
4841                                           if (e->score() == nsp->score() && e->track() == nsp->track()) {
4842                                                 nsp->setStartElement(e);
4843                                                 break;
4844                                                 }
4845                                           }
4846                                     }
4847                               if (sp->endElement()) {
4848                                     QList<ScoreElement*> eel = sp->endElement()->linkList();
4849                                     for (ScoreElement* ee : qAsConst(eel)) {
4850                                           Element* e = static_cast<Element*>(ee);
4851                                           if (e->score() == nsp->score() && e->track() == nsp->track2()) {
4852                                                 nsp->setEndElement(e);
4853                                                 break;
4854                                                 }
4855                                           }
4856                                     }
4857                               }
4858                         undo(new AddElement(nsp));
4859                         }
4860                   else if (et == ElementType::GLISSANDO)
4861                         undo(new AddElement(toSpanner(ne)));
4862                   else if (element->isTremolo() && toTremolo(element)->twoNotes()) {
4863                         Tremolo* tremolo = toTremolo(element);
4864                         ChordRest* cr1 = toChordRest(tremolo->chord1());
4865                         ChordRest* cr2 = toChordRest(tremolo->chord2());
4866                         Segment* s1    = cr1->segment();
4867                         Segment* s2    = cr2->segment();
4868                         Measure* m1    = s1->measure();
4869                         Measure* m2    = s2->measure();
4870                         Measure* nm1   = score->tick2measure(m1->tick());
4871                         Measure* nm2   = score->tick2measure(m2->tick());
4872                         Segment* ns1   = nm1->findSegment(s1->segmentType(), s1->tick());
4873                         Segment* ns2   = nm2->findSegment(s2->segmentType(), s2->tick());
4874                         Chord* c1      = toChord(ns1->element(staffIdx * VOICES + cr1->voice()));
4875                         Chord* c2      = toChord(ns2->element(staffIdx * VOICES + cr2->voice()));
4876                         Tremolo* ntremolo = toTremolo(ne);
4877                         ntremolo->setChords(c1, c2);
4878                         ntremolo->setParent(c1);
4879                         undo(new AddElement(ntremolo));
4880                         }
4881                   else if (element->isTremolo() && !toTremolo(element)->twoNotes()) {
4882                         Chord* cr = toChord(element->parent());
4883                         Chord* c1 = findLinkedChord(cr, score->staff(staffIdx));
4884                         ne->setParent(c1);
4885                         undo(new AddElement(ne));
4886                         }
4887                   else if (element->isArpeggio()) {
4888                         ChordRest* cr = toChordRest(element->parent());
4889                         Segment* s    = cr->segment();
4890                         Measure* m    = s->measure();
4891                         Measure* nm   = score->tick2measure(m->tick());
4892                         Segment* ns   = nm->findSegment(s->segmentType(), s->tick());
4893                         Chord* c1     = toChord(ns->element(staffIdx * VOICES + cr->voice()));
4894                         ne->setParent(c1);
4895                         undo(new AddElement(ne));
4896                         }
4897                   else if (element->isTie()) {
4898                         Tie* tie       = toTie(element);
4899                         Note* n1       = tie->startNote();
4900                         Note* n2       = tie->endNote();
4901                         Chord* cr1     = n1->chord();
4902                         Chord* cr2     = n2 ? n2->chord() : 0;
4903 
4904                         // find corresponding notes in linked staff
4905                         // accounting for grace notes and cross-staff notation
4906                         int sm = 0;
4907                         if (cr1->staffIdx() != cr2->staffIdx())
4908                               sm = cr2->staffIdx() - cr1->staffIdx();
4909                         Chord* c1 = findLinkedChord(cr1, score->staff(staffIdx));
4910                         Chord* c2 = findLinkedChord(cr2, score->staff(staffIdx + sm));
4911                         Note* nn1 = c1->findNote(n1->pitch(), n1->unisonIndex());
4912                         Note* nn2 = c2 ? c2->findNote(n2->pitch(), n2->unisonIndex()) : 0;
4913 
4914                         // create tie
4915                         Tie* ntie = toTie(ne);
4916                         ntie->eraseSpannerSegments();
4917                         ntie->setTrack(c1->track());
4918                         ntie->setStartNote(nn1);
4919                         ntie->setEndNote(nn2);
4920                         undo(new AddElement(ntie));
4921                         }
4922                   else if (element->isInstrumentChange()) {
4923                         InstrumentChange* is = toInstrumentChange(element);
4924                         Segment* s1    = is->segment();
4925                         Measure* m1    = s1->measure();
4926                         Measure* nm1   = score->tick2measure(m1->tick());
4927                         Segment* ns1   = nm1->findSegment(s1->segmentType(), s1->tick());
4928                         InstrumentChange* nis = toInstrumentChange(ne);
4929                         nis->setParent(ns1);
4930                         Fraction tickStart = nis->segment()->tick();
4931                         Part* part = nis->part();
4932                         Interval oldV = nis->part()->instrument(tickStart)->transpose();
4933                         // ws: instrument should not be changed here
4934                         if (is->instrument()->channel().empty() || is->instrument()->channel(0)->program() == -1)
4935                               nis->setInstrument(*staff->part()->instrument(s1->tick()));
4936                         else if (nis != is)
4937                               nis->setInstrument(*is->instrument());
4938                         undo(new AddElement(nis));
4939                         // transpose root score; parts will follow
4940                         if (score->isMaster() && part->instrument(tickStart)->transpose() != oldV) {
4941                               auto i = part->instruments()->upper_bound(tickStart.ticks());
4942                               Fraction tickEnd = i == part->instruments()->end() ? Fraction(-1, 1) : Fraction::fromTicks(i->first);
4943                               transpositionChanged(part, oldV, tickStart, tickEnd);
4944                               }
4945                         }
4946                   else if (element->isBreath()) {
4947                         Breath* breath   = toBreath(element);
4948                         Fraction tick    = breath->segment()->tick();
4949                         Measure* m       = score->tick2measure(tick);
4950                         // breath appears before barline
4951                         if (m->tick() == tick)
4952                               m = m->prevMeasure();
4953                         Segment* seg     = m->undoGetSegment(SegmentType::Breath, tick);
4954                         Breath* nbreath  = toBreath(ne);
4955                         nbreath->setScore(score);
4956                         nbreath->setTrack(ntrack);
4957                         nbreath->setParent(seg);
4958                         undo(new AddElement(nbreath));
4959                         }
4960                   else
4961                         qWarning("undoAddElement: unhandled: <%s>", element->name());
4962                   }
4963             }
4964       }
4965 
4966 //---------------------------------------------------------
4967 //   undoAddCR
4968 //---------------------------------------------------------
4969 
undoAddCR(ChordRest * cr,Measure * measure,const Fraction & tick)4970 void Score::undoAddCR(ChordRest* cr, Measure* measure, const Fraction& tick)
4971       {
4972       Q_ASSERT(!cr->isChord() || !(toChord(cr)->notes()).empty());
4973       if (!cr->lyrics().empty()) {
4974             // Add chordrest and lyrics separately for correct
4975             // handling of adding lyrics to linked staves.
4976             std::vector<Lyrics*> lyrics;
4977             std::swap(lyrics, cr->lyrics());
4978             undoAddCR(cr, measure, tick);
4979             for (Lyrics* l : lyrics)
4980                   undoAddElement(l);
4981             return;
4982             }
4983 
4984       Staff* ostaff = cr->staff();
4985       int strack    = ostaff->idx() * VOICES + cr->voice();
4986 
4987       if (ostaff->score()->excerpt() && !ostaff->score()->excerpt()->tracks().isEmpty())
4988             strack = ostaff->score()->excerpt()->tracks().key(strack, -1);
4989 
4990       SegmentType segmentType = SegmentType::ChordRest;
4991 
4992       Tuplet* crTuplet = cr->tuplet();
4993 
4994       // For linked staves the length of staffList is always > 1 since the list contains the staff itself too!
4995       const bool linked = ostaff->staffList().length() > 1;
4996 
4997       for (const Staff* staff : ostaff->staffList()) {
4998             QList<int> tracks;
4999             if (!staff->score()->excerpt()) {
5000                   // On masterScore.
5001                   int track = staff->idx() * VOICES + (strack % VOICES);
5002                   tracks.append(track);
5003                   }
5004             else {
5005                   QMultiMap<int, int> mapping = staff->score()->excerpt()->tracks();
5006                   if (mapping.isEmpty()) {
5007                         // This can happen during reading the score and there is
5008                         // no Tracklist tag specified.
5009                         // TODO solve this in read302.cpp.
5010                         tracks.append(strack);
5011                         }
5012                   else {
5013                         // linkedPart : linked staves within same part/instrument.
5014                         // linkedScore: linked staves over different scores via excerpts.
5015                         const bool linkedPart  = linked && (staff != ostaff) && (staff->score() == ostaff->score());
5016                         const bool linkedScore = linked && (staff != ostaff) && (staff->score() != ostaff->score());
5017                         for (int track : mapping.values(strack)) {
5018                               if (linkedPart && !linkedScore) {
5019                                     tracks.append(staff->idx() * VOICES + mapping.value(track));
5020                                     }
5021                               else if (!linkedPart && linkedScore) {
5022                                     if ((track >> 2) != staff->idx())
5023                                           track += (staff->idx() - (track >> 2)) * VOICES;
5024                                     tracks.append(track);
5025                                     }
5026                               else {
5027                                     tracks.append(track);
5028                                     }
5029                               }
5030                         }
5031                   }
5032 
5033             for (int ntrack : tracks) {
5034                   if (ntrack < staff->part()->startTrack() || ntrack >= staff->part()->endTrack())
5035                         continue;
5036 
5037                   Score* score = staff->score();
5038                   Measure* m   = (score == this) ? measure : score->tick2measure(tick);
5039                   if (!m)  {
5040                         qDebug("measure not found");
5041                         break;
5042                         }
5043                   Segment* seg = m->undoGetSegment(segmentType, tick);
5044 
5045                   Q_ASSERT(seg->segmentType() == segmentType);
5046 
5047                   ChordRest* newcr = (staff == ostaff) ? cr : toChordRest(cr->linkedClone());
5048                   newcr->setScore(score);
5049 
5050                   newcr->setTrack(ntrack);
5051                   newcr->setParent(seg);
5052 
5053 #ifndef QT_NO_DEBUG
5054                   if (newcr->isChord()) {
5055                         Chord* chord = toChord(newcr);
5056                         // setTpcFromPitch needs to know the note tick position
5057                         for (Note* note : chord->notes()) {
5058                               // if (note->tpc() == Tpc::TPC_INVALID)
5059                               //      note->setTpcFromPitch();
5060                               Q_ASSERT(note->tpc() != Tpc::TPC_INVALID);
5061                               }
5062                         }
5063 #endif
5064                   if (crTuplet && staff != ostaff) {
5065                         // In case of nested tuplets, get the parent tuplet.
5066                         Tuplet* parTuplet { nullptr };
5067                         if (crTuplet->tuplet()) {
5068                               // Look for a tuplet, linked to the parent tuplet of crTuplet but
5069                               // which is on the same staff as the new ChordRest.
5070                               for (auto e : crTuplet->tuplet()->linkList()) {
5071                                     Tuplet* t = toTuplet(e);
5072                                     if (t->staff() == newcr->staff()) {
5073                                           parTuplet = t;
5074                                           break;
5075                                           }
5076                                     }
5077                               }
5078 
5079                         // Look for a tuplet linked to crTuplet but is on the same staff as
5080                         // the new ChordRest. Create a new tuplet if not found.
5081                         Tuplet* newTuplet { nullptr };
5082                         for (auto e : crTuplet->linkList()) {
5083                               Tuplet* t = toTuplet(e);
5084                               if (t->staff() == newcr->staff()) {
5085                                     newTuplet = t;
5086                                     break;
5087                                     }
5088                               }
5089 
5090                         if (!newTuplet) {
5091                               newTuplet = toTuplet(crTuplet->linkedClone());
5092                               newTuplet->setTuplet(parTuplet);
5093                               newTuplet->setScore(score);
5094                               newTuplet->setTrack(newcr->track());
5095                               newTuplet->setParent(m);
5096                               }
5097 
5098                         newcr->setTuplet(newTuplet);
5099                         }
5100 
5101                   if (newcr->isRest() && (toRest(newcr)->isGap()) && !(toRest(newcr)->track() % VOICES))
5102                         toRest(newcr)->setGap(false);
5103 
5104                   undo(new AddElement(newcr));
5105                   }
5106             }
5107       }
5108 
5109 //---------------------------------------------------------
5110 //   undoRemoveElement
5111 //---------------------------------------------------------
5112 
undoRemoveElement(Element * element)5113 void Score::undoRemoveElement(Element* element)
5114       {
5115       if (!element)
5116             return;
5117       QList<Segment*> segments;
5118       for (ScoreElement* ee : element->linkList()) {
5119             Element* e = static_cast<Element*>(ee);
5120             undo(new RemoveElement(e));
5121             if (e->parent() && (e->parent()->isSegment())) {
5122                   Segment* s = toSegment(e->parent());
5123                   if (!segments.contains(s))
5124                         segments.append(s);
5125                   }
5126             if (e->parent() && e->parent()->isSystem()) {
5127                   e->setParent(0); // systems will be regenerated upon redo, so detach
5128                   }
5129             }
5130       for (Segment* s : segments) {
5131             if (s->empty()) {
5132                   if (s->header() || s->trailer())    // probably more segment types (system header)
5133                         s->setEnabled(false);
5134                   else
5135                         undo(new RemoveElement(s));
5136                   }
5137             }
5138       }
5139 
5140 //---------------------------------------------------------
5141 //   undoChangeSpannerElements
5142 //---------------------------------------------------------
5143 
undoChangeSpannerElements(Spanner * spanner,Element * startElement,Element * endElement)5144 void Score::undoChangeSpannerElements(Spanner* spanner, Element* startElement, Element* endElement)
5145       {
5146       Element* oldStartElement = spanner->startElement();
5147       Element* oldEndElement = spanner->endElement();
5148       int startDeltaTrack = startElement && oldStartElement ? startElement->track() - oldStartElement->track() : 0;
5149       int endDeltaTrack = endElement && oldEndElement ? endElement->track() - oldEndElement->track() : 0;
5150       // scan all spanners linked to this one
5151       for (ScoreElement* el : spanner->linkList()) {
5152             Spanner* sp = toSpanner(el);
5153             Element* newStartElement = nullptr;
5154             Element* newEndElement = nullptr;
5155             // if not the current spanner, but one linked to it, determine its new start and end elements
5156             // as modifications 'parallel' to the modifications of the current spanner's start and end elements
5157             if (sp != spanner) {
5158                   if (startElement) {
5159                         // determine the track where to expect the 'parallel' start element
5160                         int newTrack = sp->startElement() ? sp->startElement()->track() + startDeltaTrack : sp->track();
5161                         // look in elements linked to new start element for an element with
5162                         // same score as linked spanner and appropriate track
5163                         for (ScoreElement* ee : startElement->linkList()) {
5164                               Element* e = toElement(ee);
5165                               if (e->score() == sp->score() && e->track() == newTrack) {
5166                                     newStartElement = e;
5167                                     break;
5168                                     }
5169                               }
5170                         }
5171                   // similarly to determine the 'parallel' end element
5172                   if (endElement) {
5173                         int newTrack = sp->endElement() ? sp->endElement()->track() + endDeltaTrack : sp->track2();
5174                         for (ScoreElement* ee : endElement->linkList()) {
5175                               Element* e = toElement(ee);
5176                               if (e->score() == sp->score() && e->track() == newTrack) {
5177                                     newEndElement = e;
5178                                     break;
5179                                     }
5180                               }
5181                         }
5182                   }
5183             // if current spanner, just use stored start and end elements
5184             else {
5185                   newStartElement = startElement;
5186                   newEndElement = endElement;
5187                   }
5188             sp->score()->undo(new ChangeSpannerElements(sp, newStartElement, newEndElement));
5189             }
5190       }
5191 
5192 //---------------------------------------------------------
5193 //   undoChangeTuning
5194 //---------------------------------------------------------
5195 
undoChangeTuning(Note * n,qreal v)5196 void Score::undoChangeTuning(Note* n, qreal v)
5197       {
5198       n->undoChangeProperty(Pid::TUNING, v);
5199       }
5200 
undoChangeUserMirror(Note * n,MScore::DirectionH d)5201 void Score::undoChangeUserMirror(Note* n, MScore::DirectionH d)
5202       {
5203       n->undoChangeProperty(Pid::MIRROR_HEAD, int(d));
5204       }
5205 
5206 //---------------------------------------------------------
5207 //   undoChangeTpc
5208 //    TODO-TPC: check
5209 //---------------------------------------------------------
5210 
undoChangeTpc(Note * note,int v)5211 void Score::undoChangeTpc(Note* note, int v)
5212       {
5213       note->undoChangeProperty(Pid::TPC1, v);
5214       }
5215 
5216 //---------------------------------------------------------
5217 //   undoAddBracket
5218 //---------------------------------------------------------
5219 
undoAddBracket(Staff * staff,int level,BracketType type,int span)5220 void Score::undoAddBracket(Staff* staff, int level, BracketType type, int span)
5221       {
5222       undo(new AddBracket(staff, level, type, span));
5223       }
5224 
5225 //---------------------------------------------------------
5226 //   undoRemoveBracket
5227 //---------------------------------------------------------
5228 
undoRemoveBracket(Bracket * b)5229 void Score::undoRemoveBracket(Bracket* b)
5230       {
5231       undo(new RemoveBracket(b->staff(), b->column(), b->bracketType(), b->span()));
5232       }
5233 
5234 //---------------------------------------------------------
5235 //   undoInsertTime
5236 //   acts on the linked scores as well
5237 //---------------------------------------------------------
5238 
undoInsertTime(const Fraction & tick,const Fraction & len)5239 void Score::undoInsertTime(const Fraction& tick, const Fraction& len)
5240       {
5241       if (len.isZero())
5242             return;
5243 
5244       QList<Spanner*> sl;
5245       for (auto i : _spanner.map()) {
5246             Spanner* s = i.second;
5247             if (s->tick2() < tick)
5248                   continue;
5249             bool append = false;
5250             if (len > Fraction(0, 1)) {
5251                   if (tick > s->tick() && tick < s->tick2())
5252                         append = true;
5253                   else if (tick <= s->tick())
5254                         append = true;
5255                   }
5256             else {
5257                   Fraction tick2 = tick - len;
5258                   if (s->tick() >= tick2)
5259                         append = true;
5260                   else if (s->tick() >= tick && s->tick2() <= tick2)
5261                         append = true;
5262                   else if ((s->tick() <= tick) && (s->tick2() >= tick2)) {
5263                         Fraction t2 = s->tick2() + len;
5264                         if (t2 > s->tick())
5265                               append = true;
5266                         }
5267                   else if (s->tick() > tick && s->tick2() > tick2)
5268                         append = true;
5269                   else if (s->tick() < tick && s->tick2() < tick2)
5270                         append = true;
5271                   }
5272             for (Spanner* ss : sl) {
5273                   if (ss->linkList().contains(s)) {
5274                         append = false;
5275                         break;
5276                         }
5277                   }
5278             if (append)
5279                   sl.append(s);
5280             }
5281       for (Spanner* s : sl) {
5282             if (len > Fraction(0, 1)) {
5283                   if (tick > s->tick() && tick < s->tick2()) {
5284                         //
5285                         //  case a:
5286                         //  +----spanner--------+
5287                         //    +---add---
5288                         //
5289                         s->undoChangeProperty(Pid::SPANNER_TICKS, s->ticks() + len);
5290                         }
5291                   else if (tick <= s->tick()) {
5292                         //
5293                         //  case b:
5294                         //       +----spanner--------
5295                         //  +---add---
5296                         // and
5297                         //            +----spanner--------
5298                         //  +---add---+
5299                         Element* startElement = s->startElement();
5300                         Element* endElement = s->endElement();
5301                         undoChangeSpannerElements(s, nullptr, nullptr);
5302                         s->undoChangeProperty(Pid::SPANNER_TICK, s->tick() + len);
5303                         undoChangeSpannerElements(s, startElement, endElement);
5304                         }
5305                   }
5306             else {
5307                   Fraction tick2 = tick - len;
5308                   if (s->tick() >= tick2) {
5309                         //
5310                         //  case A:
5311                         //  +----remove---+ +---spanner---+
5312                         //
5313                         Fraction t = s->tick() + len;
5314                         if (t < Fraction(0,1))
5315                               t = Fraction(0,1);
5316                         Element* startElement = s->startElement();
5317                         Element* endElement = s->endElement();
5318                         undoChangeSpannerElements(s, nullptr, nullptr);
5319                         s->undoChangeProperty(Pid::SPANNER_TICK, t);
5320                         undoChangeSpannerElements(s, startElement, endElement);
5321                         }
5322                   else if (s->tick() >= tick && s->tick2() <= tick2) {
5323                         //
5324                         //  case B:
5325                         //    +---spanner---+
5326                         //  +----remove--------+
5327                         //
5328                         undoRemoveElement(s);
5329                         }
5330                   else if ((s->tick() <= tick) && (s->tick2() >= tick2)) {
5331                         //
5332                         //  case C:
5333                         //  +----spanner--------+
5334                         //    +---remove---+
5335                         //
5336                         Fraction t2 = s->tick2() + len;
5337                         if (t2 > s->tick())
5338                               s->undoChangeProperty(Pid::SPANNER_TICKS, s->ticks() + len);
5339                         }
5340                   else if (s->tick() > tick && s->tick2() > tick2) {
5341                         //
5342                         //  case D:
5343                         //       +----spanner--------+
5344                         //  +---remove---+
5345                         //
5346                         Fraction d1 = s->tick() - tick;
5347                         Fraction d2 = tick2 - s->tick();
5348                         Fraction le = s->ticks() - d2;
5349                         if (le.isZero())
5350                               undoRemoveElement(s);
5351                         else {
5352                               s->undoChangeProperty(Pid::SPANNER_TICK, s->tick() - d1);
5353                               s->undoChangeProperty(Pid::SPANNER_TICKS, le);
5354                               }
5355                         }
5356                   else if (s->tick() < tick && s->tick2() < tick2) {
5357                         //
5358                         //  case E:
5359                         //       +----spanner--------+
5360                         //                     +---remove---+
5361                         //
5362                         Fraction d  = s->tick2() - tick;
5363                         Fraction le = s->ticks() - d;
5364                         if (le.isZero())
5365                               undoRemoveElement(s);
5366                         else
5367                               s->undoChangeProperty(Pid::SPANNER_TICKS, le);
5368                         }
5369                   }
5370             }
5371 
5372       undo(new InsertTimeUnmanagedSpanner(this, tick, len));
5373       }
5374 
5375 //---------------------------------------------------------
5376 //   undoRemoveMeasures
5377 //---------------------------------------------------------
5378 
undoRemoveMeasures(Measure * m1,Measure * m2,bool preserveTies)5379 void Score::undoRemoveMeasures(Measure* m1, Measure* m2, bool preserveTies)
5380       {
5381       Q_ASSERT(m1 && m2);
5382 
5383       const Fraction startTick = m1->tick();
5384       const Fraction endTick = m2->endTick();
5385       std::set<Spanner*> spannersToRemove;
5386 
5387       //
5388       //  handle ties which start before m1 and end in (m1-m2)
5389       //
5390       for (Segment* s = m1->first(); s != m2->last(); s = s->next1()) {
5391             if (!s->isChordRestType())
5392                   continue;
5393             for (int track = 0; track < ntracks(); ++track) {
5394                   Element* e = s->element(track);
5395                   if (!e || !e->isChord())
5396                         continue;
5397                   Chord* c = toChord(e);
5398                   for (Note* n : c->notes()) {
5399                         // Remove ties crossing measure range boundaries
5400                         Tie* t = n->tieBack();
5401                         if (t && (t->startNote()->chord()->tick() < startTick)) {
5402                               if (preserveTies)
5403                                     t->setEndNote(0);
5404                               else
5405                                     undoRemoveElement(t);
5406                               }
5407                         t = n->tieFor();
5408                         if (t && (t->endNote()->chord()->tick() >= endTick))
5409                               undoRemoveElement(t);
5410 
5411                         // Do the same for other note-anchored spanners (e.g. glissandi).
5412                         // Delay actual removing to avoid modifying lists inside loops over them.
5413                         for (Spanner* sb : n->spannerBack()) {
5414                               if (sb->tick() < startTick)
5415                                     spannersToRemove.insert(sb);
5416                               }
5417                         for (Spanner* sf : n->spannerFor()) {
5418                               if (sf->tick2() >= endTick)
5419                                     spannersToRemove.insert(sf);
5420                               }
5421                         }
5422                   }
5423             }
5424 
5425       for (Spanner* s : spannersToRemove)
5426             undoRemoveElement(s);
5427 
5428       undo(new RemoveMeasures(m1, m2));
5429       }
5430 
5431 }
5432