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 #ifndef __SELECT_H__ 14 #define __SELECT_H__ 15 16 #include "pitchspelling.h" 17 #include "mscore.h" 18 #include "durationtype.h" 19 20 namespace Ms { 21 22 class Score; 23 class Page; 24 class System; 25 class ChordRest; 26 class Element; 27 class Segment; 28 class Note; 29 class Measure; 30 class Chord; 31 32 //--------------------------------------------------------- 33 // ElementPattern 34 //--------------------------------------------------------- 35 36 struct ElementPattern { 37 QList<Element*> el; 38 int type; 39 int subtype; 40 int staffStart; 41 int staffEnd; // exclusive 42 int voice; 43 const System* system = nullptr; 44 bool subtypeValid; 45 Fraction durationTicks; 46 Fraction beat {0,0}; 47 const Measure* measure = nullptr; 48 }; 49 50 //--------------------------------------------------------- 51 // NotePattern 52 //--------------------------------------------------------- 53 54 struct NotePattern { 55 QList<Note*> el; 56 int pitch = -1; 57 int string = STRING_NONE; 58 int tpc = Tpc::TPC_INVALID; 59 NoteHead::Group notehead = NoteHead::Group::HEAD_INVALID; 60 TDuration durationType = TDuration(); 61 Fraction durationTicks; 62 NoteType type = NoteType::INVALID; 63 int staffStart; 64 int staffEnd; // exclusive 65 int voice; 66 Fraction beat {0,0}; 67 const Measure* measure = nullptr; 68 const System* system = nullptr; 69 }; 70 71 //--------------------------------------------------------- 72 // SelState 73 //--------------------------------------------------------- 74 75 enum class SelState : char { 76 NONE, // nothing is selected 77 LIST, // disjoint selection 78 RANGE, // adjacent selection, a range in one or more staves 79 // is selected 80 }; 81 82 //--------------------------------------------------------- 83 // SelectionFilterType 84 // see also `static const char* labels[]` in mscore/selectionwindow.cpp 85 // need to keep those in sync! 86 //--------------------------------------------------------- 87 88 enum class SelectionFilterType { 89 NONE = 0, 90 FIRST_VOICE = 1 << 0, 91 SECOND_VOICE = 1 << 1, 92 THIRD_VOICE = 1 << 2, 93 FOURTH_VOICE = 1 << 3, 94 DYNAMIC = 1 << 4, 95 HAIRPIN = 1 << 5, 96 FINGERING = 1 << 6, 97 LYRICS = 1 << 7, 98 CHORD_SYMBOL = 1 << 8, 99 OTHER_TEXT = 1 << 9, 100 ARTICULATION = 1 << 10, 101 ORNAMENT = 1 << 11, 102 SLUR = 1 << 12, 103 FIGURED_BASS = 1 << 13, 104 OTTAVA = 1 << 14, 105 PEDAL_LINE = 1 << 15, 106 OTHER_LINE = 1 << 16, 107 ARPEGGIO = 1 << 17, 108 GLISSANDO = 1 << 18, 109 FRET_DIAGRAM = 1 << 19, 110 BREATH = 1 << 20, 111 TREMOLO = 1 << 21, 112 GRACE_NOTE = 1 << 22, 113 ALL = -1 114 }; 115 116 117 //--------------------------------------------------------- 118 // SelectionFilter 119 //--------------------------------------------------------- 120 121 class SelectionFilter { 122 Score* _score; 123 int _filtered; 124 125 public: SelectionFilter()126 SelectionFilter() { _score = 0; _filtered = (int)SelectionFilterType::ALL;} SelectionFilter(SelectionFilterType f)127 SelectionFilter(SelectionFilterType f) : _score(nullptr), _filtered(int(f)) {} SelectionFilter(Score * score)128 SelectionFilter(Score* score) { _score = score; _filtered = (int)SelectionFilterType::ALL;} filtered()129 int& filtered() { return _filtered; } 130 void setFiltered(SelectionFilterType type, bool set); isFiltered(SelectionFilterType type)131 bool isFiltered(SelectionFilterType type) const { return _filtered & (int)type; } 132 bool canSelect(const Element*) const; 133 bool canSelectVoice(int track) const; 134 }; 135 136 //------------------------------------------------------------------- 137 // Selection 138 // For SelState::LIST state only visible elements can be selected 139 // (no Chord element etc.). 140 //------------------------------------------------------------------- 141 142 class Selection { 143 Score* _score; 144 SelState _state; 145 QList<Element*> _el; // valid in mode SelState::LIST 146 147 int _staffStart; // valid if selState is SelState::RANGE 148 int _staffEnd; 149 Segment* _startSegment; 150 Segment* _endSegment; // next segment after selection 151 152 Fraction _plannedTick1 { -1, 1 }; // Will be actually selected on updateSelectedElements() call. 153 Fraction _plannedTick2 { -1, 1 }; // Used by setRangeTicks() to restore proper selection after 154 // command end in case some changes are expected to segments' 155 // structure (e.g. MMRests reconstruction). 156 157 Segment* _activeSegment; 158 int _activeTrack; 159 160 Fraction _currentTick; // tracks the most recent selection 161 int _currentTrack; 162 163 QString _lockReason; 164 165 QByteArray staffMimeData() const; 166 QByteArray symbolListMimeData() const; 167 SelectionFilter selectionFilter() const; canSelect(Element * e)168 bool canSelect(Element* e) const { return selectionFilter().canSelect(e); } canSelectVoice(int track)169 bool canSelectVoice(int track) const { return selectionFilter().canSelectVoice(track); } 170 void appendFiltered(Element* e); 171 void appendChord(Chord* chord); 172 173 public: Selection()174 Selection() { _score = 0; _state = SelState::NONE; } 175 Selection(Score*); score()176 Score* score() const { return _score; } state()177 SelState state() const { return _state; } isNone()178 bool isNone() const { return _state == SelState::NONE; } isRange()179 bool isRange() const { return _state == SelState::RANGE; } isList()180 bool isList() const { return _state == SelState::LIST; } 181 void setState(SelState s); 182 183 //! NOTE If locked, the selected items should not be changed. lock(const QString & reason)184 void lock(const QString& reason) { _lockReason = reason; } unlock(const QString & reason)185 void unlock(const QString& reason) { Q_UNUSED(reason); _lockReason.clear(); } // reason for clarity isLocked()186 bool isLocked() const { return !_lockReason.isEmpty(); } lockReason()187 const QString& lockReason() const { return _lockReason; } 188 elements()189 const QList<Element*>& elements() const { return _el; } 190 std::vector<Note*> noteList(int track = -1) const; 191 192 const QList<Element*> uniqueElements() const; 193 QList<Note*> uniqueNotes(int track = -1) const; 194 isSingle()195 bool isSingle() const { return (_state == SelState::LIST) && (_el.size() == 1); } 196 197 void add(Element*); 198 void deselectAll(); 199 void remove(Element*); 200 void clear(); 201 Element* element() const; 202 ChordRest* cr() const; 203 Segment* firstChordRestSegment() const; 204 ChordRest* firstChordRest(int track = -1) const; 205 ChordRest* lastChordRest(int track = -1) const; 206 Measure* findMeasure() const; 207 void update(); 208 void updateState(); 209 void dump(); 210 QString mimeType() const; 211 QByteArray mimeData() const; 212 startSegment()213 Segment* startSegment() const { return _startSegment; } endSegment()214 Segment* endSegment() const { return _endSegment; } setStartSegment(Segment * s)215 void setStartSegment(Segment* s) { _startSegment = s; } setEndSegment(Segment * s)216 void setEndSegment(Segment* s) { _endSegment = s; } 217 void setRange(Segment* startSegment, Segment* endSegment, int staffStart, int staffEnd); 218 void setRangeTicks(const Fraction& tick1, const Fraction& tick2, int staffStart, int staffEnd); activeSegment()219 Segment* activeSegment() const { return _activeSegment; } setActiveSegment(Segment * s)220 void setActiveSegment(Segment* s) { _activeSegment = s; } 221 ChordRest* activeCR() const; 222 bool isStartActive() const; 223 bool isEndActive() const; 224 ChordRest* currentCR() const; 225 Fraction tickStart() const; 226 Fraction tickEnd() const; staffStart()227 int staffStart() const { return _staffStart; } staffEnd()228 int staffEnd() const { return _staffEnd; } activeTrack()229 int activeTrack() const { return _activeTrack; } setStaffStart(int v)230 void setStaffStart(int v) { _staffStart = v; } setStaffEnd(int v)231 void setStaffEnd(int v) { _staffEnd = v; } setActiveTrack(int v)232 void setActiveTrack(int v) { _activeTrack = v; } 233 bool canCopy() const; 234 void updateSelectedElements(); 235 bool measureRange(Measure** m1, Measure** m2) const; 236 void extendRangeSelection(ChordRest* cr); 237 void extendRangeSelection(Segment* seg, Segment* segAfter, int staffIdx, const Fraction& tick, const Fraction& etick); 238 }; 239 240 241 } // namespace Ms 242 #endif 243 244