1 //=============================================================================
2 // MuseScore
3 // Music Composition & Notation
4 //
5 // Copyright (C) 2002-2011 Werner Schweer
6 //
7 // This program is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License version 2
9 // as published by the Free Software Foundation and appearing in
10 // the file LICENCE.GPL
11 //=============================================================================
12
13 /**
14 \file
15 Implementation of class Selection plus other selection related functions.
16 */
17
18 #include "global/log.h"
19
20 #include "mscore.h"
21 #include "arpeggio.h"
22 #include "barline.h"
23 #include "beam.h"
24 #include "chord.h"
25 #include "dynamic.h"
26 #include "element.h"
27 #include "figuredbass.h"
28 #include "glissando.h"
29 #include "hairpin.h"
30 #include "harmony.h"
31 #include "fret.h"
32 #include "hook.h"
33 #include "input.h"
34 #include "limits.h"
35 #include "lyrics.h"
36 #include "measure.h"
37 #include "note.h"
38 #include "notedot.h"
39 #include "page.h"
40 #include "rest.h"
41 #include "score.h"
42 #include "segment.h"
43 #include "select.h"
44 #include "sig.h"
45 #include "slur.h"
46 #include "stem.h"
47 #include "stemslash.h"
48 #include "tie.h"
49 #include "system.h"
50 #include "text.h"
51 #include "tremolo.h"
52 #include "tuplet.h"
53 #include "utils.h"
54 #include "xml.h"
55 #include "staff.h"
56 #include "part.h"
57 #include "accidental.h"
58 #include "articulation.h"
59 #include "stafftext.h"
60 #include "sticking.h"
61
62 namespace Ms {
63
64 //---------------------------------------------------------
65 // Selection
66 //---------------------------------------------------------
67
Selection(Score * s)68 Selection::Selection(Score* s)
69 {
70 _score = s;
71 _state = SelState::NONE;
72 _startSegment = 0;
73 _endSegment = 0;
74 _activeSegment = 0;
75 _staffStart = 0;
76 _staffEnd = 0;
77 _activeTrack = 0;
78 _currentTick = Fraction(-1, 1);
79 _currentTrack = 0;
80 }
81
82 //---------------------------------------------------------
83 // tickStart
84 //---------------------------------------------------------
85
tickStart() const86 Fraction Selection::tickStart() const
87 {
88 switch (_state) {
89 case SelState::RANGE:
90 return _startSegment ? _startSegment->tick() : Fraction(-1,1);
91 case SelState::LIST: {
92 ChordRest* cr = firstChordRest();
93 return (cr) ? cr->tick() : Fraction(-1,1);
94 }
95 default:
96 return Fraction(-1,1);
97 }
98 }
99
100 //---------------------------------------------------------
101 // tickEnd
102 //---------------------------------------------------------
103
tickEnd() const104 Fraction Selection::tickEnd() const
105 {
106 switch (_state) {
107 case SelState::RANGE: {
108 if (_endSegment)
109 return _endSegment->tick();
110 else { // endsegment == 0 if end of score
111 Measure* m = _score->lastMeasure();
112 return m->endTick();
113 }
114 break;
115 }
116 case SelState::LIST: {
117 ChordRest* cr = lastChordRest();
118 return (cr) ? cr->segment()->tick() : Fraction(-1,1);
119 break;
120 }
121 default:
122 return Fraction(-1,1);
123 }
124 }
125
126 //---------------------------------------------------------
127 // isStartActive
128 //---------------------------------------------------------
129
isStartActive() const130 bool Selection::isStartActive() const
131 {
132 return activeSegment() && activeSegment()->tick() == tickStart();
133 }
134
135 //---------------------------------------------------------
136 // isEndActive
137 //---------------------------------------------------------
138
isEndActive() const139 bool Selection::isEndActive() const
140 {
141 return activeSegment() && activeSegment()->tick() == tickEnd();
142 }
143
144 //---------------------------------------------------------
145 // element
146 //---------------------------------------------------------
147
element() const148 Element* Selection::element() const
149 {
150 return ((state() != SelState::RANGE) && (_el.size() == 1)) ? _el[0] : 0;
151 }
152
153 //---------------------------------------------------------
154 // cr
155 //---------------------------------------------------------
156
cr() const157 ChordRest* Selection::cr() const
158 {
159 Element* e = element();
160 if (!e)
161 return 0;
162 if (e->isNote())
163 e = e->parent();
164 if (e->isChordRest())
165 return toChordRest(e);
166 return 0;
167 }
168
169 //---------------------------------------------------------
170 // currentCR
171 //---------------------------------------------------------
172
currentCR() const173 ChordRest* Selection::currentCR() const
174 {
175 // no selection yet - start at very beginning, not first cr
176 if (_currentTick == Fraction(-1, 1))
177 return nullptr;
178 Segment* s = score()->tick2rightSegment(_currentTick, true);
179 if (!s)
180 return nullptr;
181 int track = _currentTrack;
182 // staff may have been removed - start at top
183 if (track < 0 || track >= score()->ntracks())
184 track = 0;
185 Element* e = s->element(track);
186 if (e && e->isChordRest())
187 return toChordRest(e);
188 else
189 return nullptr;
190 }
191
192 //---------------------------------------------------------
193 // activeCR
194 //---------------------------------------------------------
195
activeCR() const196 ChordRest* Selection::activeCR() const
197 {
198 if ((_state != SelState::RANGE) || !_activeSegment)
199 return 0;
200 if (_activeSegment == _startSegment)
201 return firstChordRest(_activeTrack);
202 else
203 return lastChordRest(_activeTrack);
204 }
205
firstChordRestSegment() const206 Segment* Selection::firstChordRestSegment() const
207 {
208 if (!isRange())
209 return 0;
210
211 for (Segment* s = _startSegment; s && (s != _endSegment); s = s->next1MM()) {
212 if (!s->enabled())
213 continue;
214 if (s->isChordRestType())
215 return s;
216 }
217 return 0;
218 }
219
220 //---------------------------------------------------------
221 // firstChordRest
222 //---------------------------------------------------------
223
firstChordRest(int track) const224 ChordRest* Selection::firstChordRest(int track) const
225 {
226 if (_el.size() == 1) {
227 Element* el = _el[0];
228 if (el->isNote())
229 return toChordRest(el->parent());
230 else if (el->isRest())
231 return toChordRest(el);
232 return 0;
233 }
234 ChordRest* cr = 0;
235 for (Element* el : _el) {
236 if (el->isNote())
237 el = el->parent();
238 if (el->isChordRest()) {
239 if (track != -1 && el->track() != track)
240 continue;
241 if (cr) {
242 if (toChordRest(el)->tick() < cr->tick())
243 cr = toChordRest(el);
244 }
245 else
246 cr = toChordRest(el);
247 }
248 }
249 return cr;
250 }
251
252 //---------------------------------------------------------
253 // lastChordRest
254 //---------------------------------------------------------
255
lastChordRest(int track) const256 ChordRest* Selection::lastChordRest(int track) const
257 {
258 if (_el.size() == 1) {
259 Element* el = _el[0];
260 if (el) {
261 if (el->isNote())
262 return toChordRest(el->parent());
263 else if (el->isChord() || el->isRest() || el->isRepeatMeasure())
264 return toChordRest(el);
265 }
266 return nullptr;
267 }
268 ChordRest* cr = nullptr;
269 for (auto el : _el) {
270 if (el->isNote())
271 el = toNote(el)->chord();
272 if (el->isChordRest() && toChordRest(el)->segment()->isChordRestType()) {
273 if (track != -1 && el->track() != track)
274 continue;
275 if (cr) {
276 if (toChordRest(el)->tick() >= cr->tick())
277 cr = toChordRest(el);
278 }
279 else
280 cr = toChordRest(el);
281 }
282 }
283 return cr;
284 }
285
286 //---------------------------------------------------------
287 // findMeasure
288 //---------------------------------------------------------
289
findMeasure() const290 Measure* Selection::findMeasure() const
291 {
292 Measure *m = 0;
293 if (_el.size() > 0) {
294 Element* el = _el[0];
295 m = toMeasure(el->findMeasure());
296 }
297 return m;
298 }
299
300 //---------------------------------------------------------
301 // deselectAll
302 //---------------------------------------------------------
303
deselectAll()304 void Selection::deselectAll()
305 {
306 if (_state == SelState::RANGE)
307 _score->setUpdateAll();
308 clear();
309 updateState();
310 }
311
312 //---------------------------------------------------------
313 // changeSelection
314 //---------------------------------------------------------
315
changeSelection(Element * e,bool b)316 static QRectF changeSelection(Element* e, bool b)
317 {
318 QRectF r = e->canvasBoundingRect();
319 e->setSelected(b);
320 r |= e->canvasBoundingRect();
321 return r;
322 }
323
324 //---------------------------------------------------------
325 // clear
326 //---------------------------------------------------------
327
clear()328 void Selection::clear()
329 {
330
331 IF_ASSERT_FAILED(!isLocked()) {
332 LOGE() << "selection locked, reason: " << lockReason();
333 return;
334 }
335
336 for (Element* e : qAsConst(_el)) {
337 if (e->isSpanner()) { // TODO: only visible elements should be selectable?
338 Spanner* sp = toSpanner(e);
339 for (auto s : sp->spannerSegments())
340 e->score()->addRefresh(changeSelection(s, false));
341 }
342 else
343 e->score()->addRefresh(changeSelection(e, false));
344 }
345 _el.clear();
346 _startSegment = 0;
347 _endSegment = 0;
348 _activeSegment = 0;
349 _staffStart = 0;
350 _staffEnd = 0;
351 _activeTrack = 0;
352 setState(SelState::NONE);
353 }
354
355 //---------------------------------------------------------
356 // remove
357 //---------------------------------------------------------
358
remove(Element * el)359 void Selection::remove(Element* el)
360 {
361 const bool removed = _el.removeOne(el);
362 el->setSelected(false);
363 if (removed)
364 updateState();
365 }
366
367 //---------------------------------------------------------
368 // add
369 //---------------------------------------------------------
370
add(Element * el)371 void Selection::add(Element* el)
372 {
373 IF_ASSERT_FAILED(!isLocked()) {
374 LOGE() << "selection locked, reason: " << lockReason();
375 return;
376 }
377 _el.append(el);
378 update();
379 }
380
381 //---------------------------------------------------------
382 // canSelect
383 // see also `static const char* labels[]` in selectionwindow.cpp
384 //---------------------------------------------------------
385
canSelect(const Element * e) const386 bool SelectionFilter::canSelect(const Element* e) const
387 {
388 if (e->isDynamic())
389 return isFiltered(SelectionFilterType::DYNAMIC);
390 if (e->isHairpin())
391 return isFiltered(SelectionFilterType::HAIRPIN);
392 if ((e->isArticulation() && !toArticulation(e)->isOrnament()) || e->isVibrato() || e->isFermata())
393 return isFiltered(SelectionFilterType::ARTICULATION);
394 if ((e->isArticulation() && toArticulation(e)->isOrnament()) || e->isTrill())
395 return isFiltered(SelectionFilterType::ORNAMENT);
396 if (e->type() == ElementType::LYRICS)
397 return isFiltered(SelectionFilterType::LYRICS);
398 if (e->type() == ElementType::FINGERING)
399 return isFiltered(SelectionFilterType::FINGERING);
400 if (e->type() == ElementType::HARMONY)
401 return isFiltered(SelectionFilterType::CHORD_SYMBOL);
402 if (e->type() == ElementType::SLUR)
403 return isFiltered(SelectionFilterType::SLUR);
404 if (e->type() == ElementType::FIGURED_BASS)
405 return isFiltered(SelectionFilterType::FIGURED_BASS);
406 if (e->type() == ElementType::OTTAVA)
407 return isFiltered(SelectionFilterType::OTTAVA);
408 if (e->type() == ElementType::PEDAL)
409 return isFiltered(SelectionFilterType::PEDAL_LINE);
410 if (e->type() == ElementType::ARPEGGIO)
411 return isFiltered(SelectionFilterType::ARPEGGIO);
412 if (e->type() == ElementType::GLISSANDO)
413 return isFiltered(SelectionFilterType::GLISSANDO);
414 if (e->type() == ElementType::FRET_DIAGRAM)
415 return isFiltered(SelectionFilterType::FRET_DIAGRAM);
416 if (e->type() == ElementType::BREATH)
417 return isFiltered(SelectionFilterType::BREATH);
418 if (e->isTextBase()) // only TEXT, INSTRCHANGE and STAFFTEXT are caught here, rest are system thus not in selection
419 return isFiltered(SelectionFilterType::OTHER_TEXT);
420 if (e->isSLine()) // NoteLine, Volta
421 return isFiltered(SelectionFilterType::OTHER_LINE);
422 if (e->isTremolo())
423 return isFiltered(SelectionFilterType::TREMOLO);
424 if (e->isChord() && toChord(e)->isGrace())
425 return isFiltered(SelectionFilterType::GRACE_NOTE);
426 return true;
427 }
428
429 //---------------------------------------------------------
430 // canSelectVoice
431 //---------------------------------------------------------
432
canSelectVoice(int track) const433 bool SelectionFilter::canSelectVoice(int track) const
434 {
435 int voice = track % VOICES;
436 switch (voice) {
437 case 0:
438 return isFiltered(SelectionFilterType::FIRST_VOICE);
439 case 1:
440 return isFiltered(SelectionFilterType::SECOND_VOICE);
441 case 2:
442 return isFiltered(SelectionFilterType::THIRD_VOICE);
443 case 3:
444 return isFiltered(SelectionFilterType::FOURTH_VOICE);
445 }
446 return true;
447 }
448
449 //---------------------------------------------------------
450 // appendFiltered
451 //---------------------------------------------------------
452
appendFiltered(Element * e)453 void Selection::appendFiltered(Element* e)
454 {
455 IF_ASSERT_FAILED(!isLocked()) {
456 LOGE() << "selection locked, reason: " << lockReason();
457 return;
458 }
459 if (selectionFilter().canSelect(e))
460 _el.append(e);
461 }
462
463 //---------------------------------------------------------
464 // appendChord
465 //---------------------------------------------------------
466
appendChord(Chord * chord)467 void Selection::appendChord(Chord* chord)
468 {
469 IF_ASSERT_FAILED(!isLocked()) {
470 LOGE() << "selection locked, reason: " << lockReason();
471 return;
472 }
473 if (chord->beam() && !_el.contains(chord->beam()))
474 _el.append(chord->beam());
475 if (chord->stem())
476 _el.append(chord->stem());
477 if (chord->hook())
478 _el.append(chord->hook());
479 if (chord->arpeggio())
480 appendFiltered(chord->arpeggio());
481 if (chord->stemSlash())
482 _el.append(chord->stemSlash());
483 if (chord->tremolo())
484 appendFiltered(chord->tremolo());
485 for (Note* note : chord->notes()) {
486 _el.append(note);
487 if (note->accidental()) _el.append(note->accidental());
488 foreach(Element* el, note->el())
489 appendFiltered(el);
490 for (NoteDot* dot : note->dots())
491 _el.append(dot);
492
493 if (note->tieFor() && (note->tieFor()->endElement() != 0)) {
494 if (note->tieFor()->endElement()->isNote()) {
495 Note* endNote = toNote(note->tieFor()->endElement());
496 Segment* s = endNote->chord()->segment();
497 if (s->tick() < tickEnd())
498 _el.append(note->tieFor());
499 }
500 }
501 for (Spanner* sp : note->spannerFor()) {
502 if (sp->endElement()->isNote()) {
503 Note* endNote = toNote(sp->endElement());
504 Segment* s = endNote->chord()->segment();
505 if (s->tick() < tickEnd())
506 _el.append(sp);
507 }
508 }
509 }
510 }
511
512 //---------------------------------------------------------
513 // updateSelectedElements
514 //---------------------------------------------------------
515
updateSelectedElements()516 void Selection::updateSelectedElements()
517 {
518 IF_ASSERT_FAILED(!isLocked()) {
519 LOGE() << "selection locked, reason: " << lockReason();
520 return;
521 }
522 if (_state != SelState::RANGE) {
523 update();
524 return;
525 }
526 if (_state == SelState::RANGE && _plannedTick1 != Fraction(-1,1) && _plannedTick2 != Fraction(-1,1)) {
527 const int staffStart = _staffStart;
528 const int staffEnd = _staffEnd;
529 deselectAll();
530 Segment* s1 = _score->tick2segmentMM(_plannedTick1);
531 Segment* s2 = _score->tick2segmentMM(_plannedTick2, /* first */ true);
532 if (s2 && s2->measure()->isMMRest())
533 s2 = s2->prev1MM(); // HACK both this and the previous "true"
534 // are needed to prevent bug #173381.
535 // This should exclude any segments belonging
536 // to MM-rest range from the selection.
537 if (s1 && s2 && s1->tick() + s1->ticks() > s2->tick()) {
538 // can happen with MM rests as tick2measure returns only
539 // the first segment for them.
540 return;
541 }
542 if (s2 && s2 == s2->measure()->first())
543 s2 = s2->prev1(); // we want the last segment of the previous measure
544 setRange(s1, s2, staffStart, staffEnd);
545 _plannedTick1 = Fraction(-1,1);
546 _plannedTick2 = Fraction(-1,1);
547 }
548
549 for (Element* e : qAsConst(_el))
550 e->setSelected(false);
551 _el.clear();
552
553 // assert:
554 int staves = _score->nstaves();
555 if (_staffStart < 0 || _staffStart >= staves || _staffEnd < 0 || _staffEnd > staves
556 || _staffStart >= _staffEnd) {
557 qDebug("updateSelectedElements: bad staff selection %d - %d, staves %d", _staffStart, _staffEnd, staves);
558 _staffStart = 0;
559 _staffEnd = 0;
560 }
561 int startTrack = _staffStart * VOICES;
562 int endTrack = _staffEnd * VOICES;
563
564 for (int st = startTrack; st < endTrack; ++st) {
565 if (!canSelectVoice(st))
566 continue;
567 for (Segment* s = _startSegment; s && (s != _endSegment); s = s->next1MM()) {
568 if (!s->enabled() || s->isEndBarLineType()) // do not select end bar line
569 continue;
570 for (Element* e : s->annotations()) {
571 if (e->track() != st)
572 continue;
573 appendFiltered(e);
574 }
575 Element* e = s->element(st);
576 if (!e || e->generated() || e->isTimeSig() || e->isKeySig())
577 continue;
578 if (e->isChordRest()) {
579 ChordRest* cr = toChordRest(e);
580 for (Element* el : cr->lyrics()) {
581 if (el)
582 appendFiltered(el);
583 }
584 }
585 if (e->isChord()) {
586 Chord* chord = toChord(e);
587 for (Chord* graceNote : chord->graceNotes())
588 if (canSelect(graceNote)) appendChord(graceNote);
589 appendChord(chord);
590 for (Articulation* art : chord->articulations())
591 appendFiltered(art);
592 }
593 else {
594 appendFiltered(e);
595 if (e->isRest()) {
596 Rest* r = toRest(e);
597 for (int i = 0; i < r->dots(); ++i)
598 appendFiltered(r->dot(i));
599 }
600 }
601 }
602 }
603 Fraction stick = startSegment()->tick();
604 Fraction etick = tickEnd();
605
606 for (auto i = _score->spanner().begin(); i != _score->spanner().end(); ++i) {
607 Spanner* sp = (*i).second;
608 // ignore spanners belonging to other tracks
609 if (sp->track() < startTrack || sp->track() >= endTrack)
610 continue;
611 if (!canSelectVoice(sp->track()))
612 continue;
613 // ignore voltas
614 if (sp->isVolta())
615 continue;
616 if (sp->isSlur()) {
617 // ignore if start & end elements not calculated yet
618 if (!sp->startElement() || !sp->endElement())
619 continue;
620 if ((sp->tick() >= stick && sp->tick() < etick) || (sp->tick2() >= stick && sp->tick2() < etick))
621 if (canSelect(sp->startCR()) && canSelect(sp->endCR()))
622 appendFiltered(sp); // slur with start or end in range selection
623 }
624 else if ((sp->tick() >= stick && sp->tick() < etick) && (sp->tick2() >= stick && sp->tick2() <= etick))
625 appendFiltered(sp); // spanner with start and end in range selection
626 }
627 update();
628 }
629
630 //---------------------------------------------------------
631 // setRange
632 //---------------------------------------------------------
633
setRange(Segment * startSegment,Segment * endSegment,int staffStart,int staffEnd)634 void Selection::setRange(Segment* startSegment, Segment* endSegment, int staffStart, int staffEnd)
635 {
636 Q_ASSERT(staffEnd > staffStart && staffStart >= 0 && staffEnd >= 0 && staffEnd <= _score->nstaves());
637 Q_ASSERT(!(endSegment && !startSegment));
638
639 _startSegment = startSegment;
640 _endSegment = endSegment;
641 _activeSegment = endSegment;
642 _staffStart = staffStart;
643 _staffEnd = staffEnd;
644 setState(SelState::RANGE);
645 }
646
647 //---------------------------------------------------------
648 // setRangeTicks
649 // sets the range to be selected on next
650 // updateSelectedElements() call. Can be used if some
651 // segment structure changes are expected (e.g. if
652 // creating MM rests is pending).
653 //---------------------------------------------------------
654
setRangeTicks(const Fraction & tick1,const Fraction & tick2,int staffStart,int staffEnd)655 void Selection::setRangeTicks(const Fraction& tick1, const Fraction& tick2, int staffStart, int staffEnd)
656 {
657 Q_ASSERT(staffEnd > staffStart && staffStart >= 0 && staffEnd >= 0 && staffEnd <= _score->nstaves());
658
659 deselectAll();
660 _plannedTick1 = tick1;
661 _plannedTick2 = tick2;
662 _startSegment = _endSegment = _activeSegment = nullptr;
663 _staffStart = staffStart;
664 _staffEnd = staffEnd;
665 setState(SelState::RANGE);
666 }
667
668 //---------------------------------------------------------
669 // update
670 /// Set select flag for all Elements in select list.
671 //---------------------------------------------------------
672
update()673 void Selection::update()
674 {
675 for (Element* e : qAsConst(_el))
676 e->setSelected(true);
677 updateState();
678 }
679
680 //---------------------------------------------------------
681 // dump
682 //---------------------------------------------------------
683
dump()684 void Selection::dump()
685 {
686 qDebug("Selection dump: ");
687 switch(_state) {
688 case SelState::NONE: qDebug("NONE"); return;
689 case SelState::RANGE: qDebug("RANGE"); break;
690 case SelState::LIST: qDebug("LIST"); break;
691 }
692 foreach(const Element* e, _el)
693 qDebug(" %p %s", e, e->name());
694 }
695
696 //---------------------------------------------------------
697 // updateState
698 /// update selection and input state
699 //---------------------------------------------------------
700
updateState()701 void Selection::updateState()
702 {
703 int n = _el.size();
704 Element* e = element();
705 if (n == 0)
706 setState(SelState::NONE);
707 else if (_state == SelState::NONE)
708 setState(SelState::LIST);
709 if (e) {
710 if (e->isSpannerSegment())
711 _currentTick = toSpannerSegment(e)->spanner()->tick();
712 else
713 _currentTick = e->tick();
714 // ignore system elements (e.g., frames)
715 if (e->track() >= 0)
716 _currentTrack = e->track();
717 }
718 }
719
720 //---------------------------------------------------------
721 // setState
722 //---------------------------------------------------------
723
setState(SelState s)724 void Selection::setState(SelState s)
725 {
726 _state = s;
727 _score->setSelectionChanged(true);
728 }
729
730 //---------------------------------------------------------
731 // mimeType
732 //---------------------------------------------------------
733
mimeType() const734 QString Selection::mimeType() const
735 {
736 switch (_state) {
737 default:
738 case SelState::NONE:
739 return QString();
740 case SelState::LIST:
741 return isSingle() ? mimeSymbolFormat : mimeSymbolListFormat;
742 case SelState::RANGE:
743 return mimeStaffListFormat;
744 }
745 }
746
747 //---------------------------------------------------------
748 // mimeData
749 //---------------------------------------------------------
750
mimeData() const751 QByteArray Selection::mimeData() const
752 {
753 QByteArray a;
754 switch (_state) {
755 case SelState::LIST:
756 if (isSingle())
757 a = element()->mimeData(QPointF());
758 else
759 a = symbolListMimeData();
760 break;
761 case SelState::NONE:
762 break;
763 case SelState::RANGE:
764 a = staffMimeData();
765 break;
766 }
767 return a;
768 }
769
770 //---------------------------------------------------------
771 // hasElementInTrack
772 //---------------------------------------------------------
773
hasElementInTrack(Segment * startSeg,Segment * endSeg,int track)774 bool hasElementInTrack(Segment* startSeg, Segment* endSeg, int track)
775 {
776 for (Segment* seg = startSeg; seg != endSeg; seg = seg->next1MM()) {
777 if (!seg->enabled())
778 continue;
779 if (seg->element(track))
780 return true;
781 }
782 return false;
783 }
784
785 //---------------------------------------------------------
786 // firstElementInTrack
787 //---------------------------------------------------------
788
firstElementInTrack(Segment * startSeg,Segment * endSeg,int track)789 static Fraction firstElementInTrack(Segment* startSeg, Segment* endSeg, int track)
790 {
791 for (Segment* seg = startSeg; seg != endSeg; seg = seg->next1MM()) {
792 if (!seg->enabled())
793 continue;
794 if (seg->element(track))
795 return seg->tick();
796 }
797 return Fraction(-1,1);
798 }
799
800 //---------------------------------------------------------
801 // staffMimeData
802 //---------------------------------------------------------
803
staffMimeData() const804 QByteArray Selection::staffMimeData() const
805 {
806 QBuffer buffer;
807 buffer.open(QIODevice::WriteOnly);
808 XmlWriter xml(score(), &buffer);
809 xml.header();
810 xml.setClipboardmode(true);
811 xml.setFilter(selectionFilter());
812
813 Fraction ticks = tickEnd() - tickStart();
814 int staves = staffEnd() - staffStart();
815 if (!MScore::testMode) {
816 xml.stag(QString("StaffList version=\"" MSC_VERSION "\" tick=\"%1\" len=\"%2\" staff=\"%3\" staves=\"%4\"").arg(tickStart().ticks()).arg(ticks.ticks()).arg(staffStart()).arg(staves));
817 }
818 else {
819 xml.stag(QString("StaffList version=\"2.00\" tick=\"%1\" len=\"%2\" staff=\"%3\" staves=\"%4\"").arg(tickStart().ticks()).arg(ticks.ticks()).arg(staffStart()).arg(staves));
820 }
821 Segment* seg1 = _startSegment;
822 Segment* seg2 = _endSegment;
823
824 for (int staffIdx = staffStart(); staffIdx < staffEnd(); ++staffIdx) {
825 int startTrack = staffIdx * VOICES;
826 int endTrack = startTrack + VOICES;
827
828 xml.stag(QString("Staff id=\"%1\"").arg(staffIdx));
829
830 Staff* staff = _score->staff(staffIdx);
831 Part* part = staff->part();
832 Interval interval = part->instrument(seg1->tick())->transpose();
833 if (interval.chromatic)
834 xml.tag("transposeChromatic", interval.chromatic);
835 if (interval.diatonic)
836 xml.tag("transposeDiatonic", interval.diatonic);
837 xml.stag("voiceOffset");
838 for (int voice = 0; voice < VOICES; voice++) {
839 if (hasElementInTrack(seg1, seg2, startTrack + voice)
840 && xml.canWriteVoice(voice)) {
841 Fraction offset = firstElementInTrack(seg1, seg2, startTrack+voice) - tickStart();
842 xml.tag(QString("voice id=\"%1\"").arg(voice), offset.ticks());
843 }
844 }
845 xml.etag(); // </voiceOffset>
846 xml.setCurTrack(startTrack);
847 _score->writeSegments(xml, startTrack, endTrack, seg1, seg2, false, false);
848 xml.etag();
849 }
850
851 xml.etag();
852 buffer.close();
853 return buffer.buffer();
854 }
855
856 //---------------------------------------------------------
857 // symbolListMimeData
858 //---------------------------------------------------------
859
symbolListMimeData() const860 QByteArray Selection::symbolListMimeData() const
861 {
862 struct MapData {
863 Element* e;
864 Segment* s;
865 };
866
867 QBuffer buffer;
868 buffer.open(QIODevice::WriteOnly);
869 XmlWriter xml(score(), &buffer);
870 xml.header();
871 xml.setClipboardmode(true);
872
873 int topTrack = 1000000;
874 int bottomTrack = 0;
875 Segment* firstSeg = 0;
876 Fraction firstTick = Fraction(0x7FFFFFFF,1);
877 MapData mapData;
878 Segment* seg = 0;
879 std::multimap<qint64, MapData> map;
880
881 // scan selection element list, inserting relevant elements in a tick-sorted map
882 foreach (Element* e, _el) {
883 switch (e->type()) {
884 /* All these element types are ignored:
885
886 Enabling copying of more element types requires enabling pasting in Score::pasteSymbols() in libmscore/paste.cpp
887
888 case ElementType::SYMBOL:
889 case ElementType::TEXT:
890 case ElementType::INSTRUMENT_NAME:
891 case ElementType::SLUR_SEGMENT:
892 case ElementType::TIE_SEGMENT:
893 case ElementType::STAFF_LINES:
894 case ElementType::BAR_LINE:
895 case ElementType::STEM_SLASH:
896 case ElementType::LINE:
897 case ElementType::BRACKET:
898 case ElementType::ARPEGGIO:
899 case ElementType::ACCIDENTAL:
900 case ElementType::STEM:
901 case ElementType::NOTE:
902 case ElementType::CLEF:
903 case ElementType::KEYSIG:
904 case ElementType::TIMESIG:
905 case ElementType::REST:
906 case ElementType::BREATH:
907 case ElementType::GLISSANDO:
908 case ElementType::REPEAT_MEASURE:
909 case ElementType::IMAGE:
910 case ElementType::TIE:
911 case ElementType::CHORDLINE:
912 case ElementType::BEAM:
913 case ElementType::HOOK:
914 case ElementType::MARKER:
915 case ElementType::JUMP:
916 case ElementType::FINGERING:
917 case ElementType::TUPLET:
918 case ElementType::TEMPO_TEXT:
919 case ElementType::STAFF_TEXT:
920 case ElementType::SYSTEM_TEXT:
921 case ElementType::REHEARSAL_MARK:
922 case ElementType::INSTRUMENT_CHANGE:
923 case ElementType::BEND:
924 case ElementType::TREMOLOBAR:
925 case ElementType::VOLTA:
926 case ElementType::OTTAVA_SEGMENT:
927 case ElementType::TRILL_SEGMENT:
928 case ElementType::VIBRATO_SEGMENT:
929 case ElementType::TEXTLINE_SEGMENT:
930 case ElementType::VOLTA_SEGMENT:
931 case ElementType::PEDAL_SEGMENT:
932 case ElementType::LAYOUT_BREAK:
933 case ElementType::SPACER:
934 case ElementType::STAFF_STATE:
935 case ElementType::LEDGER_LINE:
936 case ElementType::NOTEHEAD:
937 case ElementType::NOTEDOT:
938 case ElementType::TREMOLO:
939 case ElementType::MEASURE:
940 case ElementType::SELECTION:
941 case ElementType::LASSO:
942 case ElementType::SHADOW_NOTE:
943 case ElementType::RUBBERBAND:
944 case ElementType::TAB_DURATION_SYMBOL:
945 case ElementType::FSYMBOL:
946 case ElementType::PAGE:
947 case ElementType::OTTAVA:
948 case ElementType::PEDAL:
949 case ElementType::TRILL:
950 case ElementType::TEXTLINE:
951 case ElementType::NOTELINE:
952 case ElementType::SEGMENT:
953 case ElementType::SYSTEM:
954 case ElementType::COMPOUND:
955 case ElementType::CHORD:
956 case ElementType::SLUR:
957 case ElementType::ELEMENT:
958 case ElementType::ELEMENT_LIST:
959 case ElementType::STAFF_LIST:
960 case ElementType::MEASURE_LIST:
961 case ElementType::LAYOUT:
962 case ElementType::HBOX:
963 case ElementType::VBOX:
964 case ElementType::TBOX:
965 case ElementType::FBOX:
966 case ElementType::ICON:
967 case ElementType::OSSIA:
968 case ElementType::BAGPIPE_EMBELLISHMENT:
969 continue;
970 */
971 case ElementType::ARTICULATION:
972 // ignore articulations not attached to chords/rest
973 if (e->parent()->isChord()) {
974 Chord* par = toChord(e->parent());
975 seg = par->segment();
976 break;
977 }
978 else if (e->parent()->isRest()) {
979 Rest* par = toRest(e->parent());
980 seg = par->segment();
981 break;
982 }
983 continue;
984 case ElementType::STAFF_TEXT:
985 seg = toStaffText(e)->segment();
986 break;
987 case ElementType::STICKING:
988 seg = toSticking(e)->segment();
989 break;
990 case ElementType::FIGURED_BASS:
991 seg = toFiguredBass(e)->segment();
992 break;
993 case ElementType::HARMONY:
994 case ElementType::FRET_DIAGRAM:
995 // ignore chord symbols or fret diagrams not attached to segment
996 if (e->parent()->isSegment()) {
997 seg = toSegment(e->parent());
998 break;
999 }
1000 continue;
1001 case ElementType::LYRICS:
1002 seg = toLyrics(e)->segment();
1003 break;
1004 case ElementType::DYNAMIC:
1005 seg = toDynamic(e)->segment();
1006 break;
1007 case ElementType::HAIRPIN_SEGMENT:
1008 e = toHairpinSegment(e)->hairpin();
1009 // fall through
1010 case ElementType::HAIRPIN:
1011 seg = toHairpin(e)->startSegment();
1012 break;
1013 default:
1014 continue;
1015 }
1016 int track = e->track();
1017 if (track < topTrack)
1018 topTrack = track;
1019 if (track > bottomTrack)
1020 bottomTrack = track;
1021 if (seg->tick() < firstTick) {
1022 firstSeg = seg;
1023 firstTick = seg->tick();
1024 }
1025 mapData.e = e;
1026 mapData.s = seg;
1027 map.insert(std::pair<qint64,MapData>( ((qint64)track << 32) + seg->tick().ticks(), mapData));
1028 }
1029
1030 xml.stag(QString("SymbolList version=\"" MSC_VERSION "\" fromtrack=\"%1\" totrack=\"%2\"")
1031 .arg(topTrack).arg(bottomTrack));
1032 // scan the map, outputting elements each with a relative <track> tag on track change,
1033 // a relative tick and the number of CR segments to skip
1034 int currTrack = -1;
1035 for (auto iter = map.cbegin(); iter != map.cend(); ++iter) {
1036 int numSegs;
1037 int track = static_cast<int>(iter->first >> 32);
1038 if (currTrack != track) {
1039 xml.tag("trackOffset", track - topTrack);
1040 currTrack = track;
1041 seg = firstSeg;
1042 }
1043 xml.tag("tickOffset", static_cast<int>(iter->first & 0xFFFFFFFF) - firstTick.ticks());
1044 numSegs = 0;
1045 // with figured bass, we need to look for the proper segment
1046 // not only according to ChordRest elements, but also annotations
1047 if (iter->second.e->type() == ElementType::FIGURED_BASS) {
1048 bool done = false;
1049 for ( ; seg; seg = seg->next1()) {
1050 if (seg->isChordRestType()) {
1051 // if no ChordRest in right track, look in anotations
1052 if (seg->element(currTrack) == nullptr) {
1053 foreach (Element* el, seg->annotations()) {
1054 // do annotations include our element?
1055 if (el == iter->second.e) {
1056 done = true;
1057 break;
1058 }
1059 // do annotations include any f.b.?
1060 if (el->type() == ElementType::FIGURED_BASS && el->track() == track) {
1061 numSegs++; //yes: it counts as a step
1062 break;
1063 }
1064 }
1065 if (done)
1066 break;
1067 continue; // segment is not relevant: no ChordRest nor f.b.
1068 }
1069 else {
1070 if (iter->second.s == seg)
1071 break;
1072 }
1073 numSegs++;
1074 }
1075 }
1076 }
1077 else {
1078 while (seg && iter->second.s != seg) {
1079 seg = seg->nextCR(currTrack);
1080 numSegs++;
1081 }
1082 }
1083 xml.tag("segDelta", numSegs);
1084 iter->second.e->write(xml);
1085 }
1086
1087 xml.etag();
1088 buffer.close();
1089 return buffer.buffer();
1090 }
1091
1092 //---------------------------------------------------------
1093 // noteList
1094 //---------------------------------------------------------
1095
noteList(int selTrack) const1096 std::vector<Note*> Selection::noteList(int selTrack) const
1097 {
1098 std::vector<Note*>nl;
1099
1100 if (_state == SelState::LIST) {
1101 foreach(Element* e, _el) {
1102 if (e->isNote())
1103 nl.push_back(toNote(e));
1104 }
1105 }
1106 else if (_state == SelState::RANGE) {
1107 for (int staffIdx = staffStart(); staffIdx < staffEnd(); ++staffIdx) {
1108 int startTrack = staffIdx * VOICES;
1109 int endTrack = startTrack + VOICES;
1110 for (Segment* seg = _startSegment; seg && seg != _endSegment; seg = seg->next1()) {
1111 if (!(seg->segmentType() & (SegmentType::ChordRest)))
1112 continue;
1113 for (int track = startTrack; track < endTrack; ++track) {
1114 if (!canSelectVoice(track))
1115 continue;
1116 Element* e = seg->element(track);
1117 if (e == 0 || e->type() != ElementType::CHORD
1118 || (selTrack != -1 && selTrack != track))
1119 continue;
1120 Chord* c = toChord(e);
1121 nl.insert(nl.end(), c->notes().begin(), c->notes().end());
1122 for (Chord* g : c->graceNotes()) {
1123 nl.insert(nl.end(), g->notes().begin(), g->notes().end());
1124 }
1125 }
1126 }
1127 }
1128 }
1129 return nl;
1130 }
1131
1132 //---------------------------------------------------------
1133 // checkStart
1134 // return false if element is NOT a tuplet or is start of a tuplet/tremolo
1135 // return true if element is part of a tuplet/tremolo, but not the start
1136 //---------------------------------------------------------
1137
checkStart(Element * e)1138 static bool checkStart(Element* e)
1139 {
1140 if (e == 0 || !e->isChordRest())
1141 return false;
1142 ChordRest* cr = toChordRest(e);
1143 bool rv = false;
1144 if (cr->tuplet()) {
1145 // check that complete tuplet is selected, all the way up to top level
1146 Tuplet* tuplet = cr->tuplet();
1147 while (tuplet) {
1148 if (tuplet->elements().front() != e)
1149 return true;
1150 e = tuplet;
1151 tuplet = tuplet->tuplet();
1152 }
1153 }
1154 else if (cr->type() == ElementType::CHORD) {
1155 rv = false;
1156 Chord* chord = toChord(cr);
1157 if (chord->tremolo() && chord->tremolo()->twoNotes())
1158 rv = chord->tremolo()->chord2() == chord;
1159 }
1160 return rv;
1161 }
1162
1163 //---------------------------------------------------------
1164 // checkEnd
1165 // return false if element is NOT a tuplet or is end of a tuplet
1166 // return true if element is part of a tuplet, but not the end
1167 //---------------------------------------------------------
1168
checkEnd(Element * e,const Fraction & endTick)1169 static bool checkEnd(Element* e, const Fraction& endTick)
1170 {
1171 if (e == 0 || !e->isChordRest())
1172 return false;
1173 ChordRest* cr = toChordRest(e);
1174 bool rv = false;
1175 if (cr->tuplet()) {
1176 // check that complete tuplet is selected, all the way up to top level
1177 Tuplet* tuplet = cr->tuplet();
1178 while (tuplet) {
1179 if (tuplet->elements().back() != e)
1180 return true;
1181 e = tuplet;
1182 tuplet = tuplet->tuplet();
1183 }
1184 // also check that the selection extends to the end of the top-level tuplet
1185 tuplet = toTuplet(e);
1186 if (tuplet->elements().front()->tick() + tuplet->actualTicks() > endTick)
1187 return true;
1188 }
1189 else if (cr->type() == ElementType::CHORD) {
1190 rv = false;
1191 Chord* chord = toChord(cr);
1192 if (chord->tremolo() && chord->tremolo()->twoNotes())
1193 rv = chord->tremolo()->chord1() == chord;
1194 }
1195 return rv;
1196 }
1197
1198 //---------------------------------------------------------
1199 // canCopy
1200 // return false if range selection intersects a tuplet
1201 // or a tremolo, or a local time signature
1202 //---------------------------------------------------------
1203
canCopy() const1204 bool Selection::canCopy() const
1205 {
1206 if (_state != SelState::RANGE)
1207 return true;
1208
1209 Fraction endTick = _endSegment ? _endSegment->tick() : _score->lastSegment()->tick();
1210
1211 for (int staffIdx = _staffStart; staffIdx != _staffEnd; ++staffIdx) {
1212
1213 for (int voice = 0; voice < VOICES; ++voice) {
1214 int track = staffIdx * VOICES + voice;
1215 if (!canSelectVoice(track))
1216 continue;
1217
1218 // check first cr in track within selection
1219 ChordRest* check = _startSegment->nextChordRest(track);
1220 if (check && check->tick() < endTick && checkStart(check))
1221 return false;
1222
1223 if (! _endSegment)
1224 continue;
1225
1226 // find last segment in the selection.
1227 // Note that _endSegment is the first segment after the selection
1228
1229 Segment *endSegmentSelection = _startSegment;
1230 while (endSegmentSelection->nextCR(track) &&
1231 (endSegmentSelection->nextCR(track)->tick() < _endSegment->tick()))
1232 endSegmentSelection = endSegmentSelection->nextCR(track);
1233
1234 if (checkEnd(endSegmentSelection->element(track), endTick))
1235 return false;
1236 }
1237
1238 // loop through measures on this staff checking for local time signatures
1239 for (Measure* m = _startSegment->measure(); m && m->tick() < endTick; m = m->nextMeasure()) {
1240 if (_score->staff(staffIdx)->isLocalTimeSignature(m->tick()))
1241 return false;
1242 }
1243
1244 }
1245 return true;
1246 }
1247
1248 //---------------------------------------------------------
1249 // measureRange
1250 // return false if no measure range selected
1251 //---------------------------------------------------------
1252
measureRange(Measure ** m1,Measure ** m2) const1253 bool Selection::measureRange(Measure** m1, Measure** m2) const
1254 {
1255 if (!isRange())
1256 return false;
1257 *m1 = startSegment()->measure();
1258 Segment* s2 = endSegment();
1259 *m2 = s2 ? s2->measure() : _score->lastMeasure();
1260 if (*m1 == *m2)
1261 return true;
1262 // if selection extends to last segment of a measure,
1263 // then endSegment() will point to next measure
1264 // this won't normally happen because end barlines are excluded from range selection
1265 // but just in case, detect this and back up one measure
1266 if (*m2 && s2 && (*m2)->tick() == s2->tick())
1267 *m2 = (*m2)->prevMeasure();
1268 return true;
1269 }
1270
1271 //---------------------------------------------------------
1272 // uniqueElements
1273 // Return list of selected elements.
1274 // If some elements are linked, only one of the linked
1275 // elements show up in the list.
1276 //---------------------------------------------------------
1277
uniqueElements() const1278 const QList<Element*> Selection::uniqueElements() const
1279 {
1280 QList<Element*> l;
1281
1282 for (Element* e : elements()) {
1283 bool alreadyThere = false;
1284 for (Element* ee : l) {
1285 if ((ee->links() && ee->links()->contains(e)) || e == ee) {
1286 alreadyThere = true;
1287 break;
1288 }
1289 }
1290 if (!alreadyThere)
1291 l.append(e);
1292 }
1293 return l;
1294 }
1295
1296 //---------------------------------------------------------
1297 // uniqueNotes
1298 // Return list of selected notes.
1299 // If some notes are linked, only one of the linked
1300 // elements show up in the list.
1301 //---------------------------------------------------------
1302
uniqueNotes(int track) const1303 QList<Note*> Selection::uniqueNotes(int track) const
1304 {
1305 QList<Note*> l;
1306
1307 for (Note* nn : noteList(track)) {
1308 for (Note* note : nn->tiedNotes()) {
1309 bool alreadyThere = false;
1310 for (Note* n : l) {
1311 if ((n->links() && n->links()->contains(note)) || n == note) {
1312 alreadyThere = true;
1313 break;
1314 }
1315 }
1316 if (!alreadyThere)
1317 l.append(note);
1318 }
1319 }
1320 return l;
1321 }
1322
1323 //---------------------------------------------------------
1324 // extendRangeSelection
1325 // Extends the range selection to contain the given
1326 // chord rest.
1327 //---------------------------------------------------------
1328
extendRangeSelection(ChordRest * cr)1329 void Selection::extendRangeSelection(ChordRest* cr)
1330 {
1331 extendRangeSelection(cr->segment(),
1332 cr->nextSegmentAfterCR(SegmentType::ChordRest
1333 | SegmentType::EndBarLine
1334 | SegmentType::Clef),
1335 cr->staffIdx(),
1336 cr->tick(),
1337 cr->tick());
1338 }
1339
1340 //---------------------------------------------------------
1341 // extendRangeSelection
1342 // Extends the range selection to contain the given
1343 // segment. SegAfter should represent the segment
1344 // that is after seg. Tick and etick represent
1345 // the start and end tick of an element. Useful when
1346 // extending by a chord rest.
1347 //---------------------------------------------------------
1348
extendRangeSelection(Segment * seg,Segment * segAfter,int staffIdx,const Fraction & tick,const Fraction & etick)1349 void Selection::extendRangeSelection(Segment* seg, Segment* segAfter, int staffIdx, const Fraction& tick, const Fraction& etick)
1350 {
1351 bool activeIsFirst = false;
1352 int activeStaff = _activeTrack / VOICES;
1353
1354 if (staffIdx < _staffStart)
1355 _staffStart = staffIdx;
1356 else if (staffIdx >= _staffEnd)
1357 _staffEnd = staffIdx + 1;
1358 else if (_staffEnd - _staffStart > 1) { // at least 2 staff selected
1359 if (staffIdx == _staffStart + 1 && activeStaff == _staffStart) // going down
1360 _staffStart = staffIdx;
1361 else if (staffIdx == _staffEnd - 2 && activeStaff == _staffEnd - 1) // going up
1362 _staffEnd = staffIdx + 1;
1363 }
1364
1365 if (tick < tickStart()) {
1366 _startSegment = seg;
1367 activeIsFirst = true;
1368 }
1369 else if (etick >= tickEnd()) {
1370 _endSegment = segAfter;
1371 }
1372 else {
1373 if (_activeSegment == _startSegment) {
1374 _startSegment = seg;
1375 activeIsFirst = true;
1376 }
1377 else {
1378 _endSegment = segAfter;
1379 }
1380 }
1381 activeIsFirst ? _activeSegment = _startSegment : _activeSegment = _endSegment;
1382 _score->setSelectionChanged(true);
1383 Q_ASSERT(!(_endSegment && !_startSegment));
1384 }
1385
1386 //---------------------------------------------------------
1387 // selectionFilter
1388 //---------------------------------------------------------
1389
selectionFilter() const1390 SelectionFilter Selection::selectionFilter() const
1391 {
1392 return _score->selectionFilter();
1393 }
1394
1395 //---------------------------------------------------------
1396 // setFiltered
1397 //---------------------------------------------------------
1398
setFiltered(SelectionFilterType type,bool set)1399 void SelectionFilter::setFiltered(SelectionFilterType type, bool set)
1400 {
1401 if (set)
1402 _filtered = _filtered | (int)type;
1403 else
1404 _filtered = _filtered & ~(int)type;
1405 }
1406 }
1407
1408