1 //=============================================================================
2 // MuseScore
3 // Music Composition & Notation
4 //
5 // Copyright (C) 2017 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 __SCORE_ELEMENT_H__
14 #define __SCORE_ELEMENT_H__
15
16 #include "types.h"
17 #include "style.h"
18
19 namespace Ms {
20
21 class ScoreElement;
22 class MasterScore;
23 class XmlWriter;
24 class ConnectorInfoReader;
25 class Measure;
26 class Staff;
27 class Part;
28 class Score;
29 class Sym;
30 class MuseScoreView;
31 class Segment;
32 class Element;
33 class BarLine;
34 class Articulation;
35 class Marker;
36 class Clef;
37 class KeySig;
38 class TimeSig;
39 class TempoText;
40 class Breath;
41 class Box;
42 class HBox;
43 class VBox;
44 class TBox;
45 class FBox;
46 class ChordRest;
47 class Slur;
48 class Tie;
49 class Glissando;
50 class GlissandoSegment;
51 class SystemDivider;
52 class RehearsalMark;
53 class Harmony;
54 class Volta;
55 class Jump;
56 class StaffText;
57 class Ottava;
58 class Note;
59 class Chord;
60 class Rest;
61 class LayoutBreak;
62 class Tremolo;
63 class System;
64 class Sticking;
65 class Lyrics;
66 class LyricsLine;
67 class LyricsLineSegment;
68 class Stem;
69 class SlurSegment;
70 class TieSegment;
71 class OttavaSegment;
72 class Beam;
73 class Hook;
74 class StemSlash;
75 class Spacer;
76 class StaffLines;
77 class Ambitus;
78 class Bracket;
79 class InstrumentChange;
80 class Text;
81 class TextBase;
82 class Hairpin;
83 class HairpinSegment;
84 class Bend;
85 class TremoloBar;
86 class RepeatMeasure;
87 class Tuplet;
88 class NoteDot;
89 class Dynamic;
90 class InstrumentName;
91 class DurationElement;
92 class Accidental;
93 class TextLine;
94 class TextLineSegment;
95 class Pedal;
96 class PedalSegment;
97 class LedgerLine;
98 class Icon;
99 class VoltaSegment;
100 class NoteLine;
101 class Trill;
102 class TrillSegment;
103 class Symbol;
104 class FSymbol;
105 class Fingering;
106 class NoteHead;
107 class FiguredBass;
108 class StaffState;
109 class Arpeggio;
110 class Image;
111 class ChordLine;
112 class SlurTieSegment;
113 class FretDiagram;
114 class StaffTypeChange;
115 class MeasureBase;
116 class Page;
117 class SystemText;
118 class BracketItem;
119 class Spanner;
120 class SpannerSegment;
121 class Lasso;
122 class BagpipeEmbellishment;
123 class LineSegment;
124 class BSymbol;
125 class TextLineBase;
126 class Fermata;
127
128 class LetRing;
129 class LetRingSegment;
130 class Vibrato;
131 class VibratoSegment;
132 class PalmMute;
133 class PalmMuteSegment;
134 class MeasureNumber;
135 class MMRestRange;
136
137 class StaffTextBase;
138
139 enum class Pid : int;
140 enum class PropertyFlags : char;
141
142 //---------------------------------------------------------
143 // LinkedElements
144 //---------------------------------------------------------
145
146 class LinkedElements : public QList<ScoreElement*> {
147 int _lid; // unique id for every linked list
148
149 public:
150 LinkedElements(Score*);
151 LinkedElements(Score*, int id);
152
153 void setLid(Score*, int val);
lid()154 int lid() const { return _lid; }
155
156 ScoreElement* mainElement();
157 };
158
159 //---------------------------------------------------------
160 // ElementName
161 //---------------------------------------------------------
162
163 struct ElementName {
164 ElementType type;
165 const char* name;
166 const char* userName;
167 };
168
169 //---------------------------------------------------------
170 // ScoreElement
171 //---------------------------------------------------------
172
173 class ScoreElement {
174 Score* _score;
175 static ElementStyle const emptyStyle;
176
177 protected:
178 const ElementStyle* _elementStyle { &emptyStyle };
179 PropertyFlags* _propertyFlagsList { 0 };
180 LinkedElements* _links { 0 };
181 virtual int getPropertyFlagsIdx(Pid id) const;
182
183 public:
ScoreElement(Score * s)184 ScoreElement(Score* s) : _score(s) {}
185 ScoreElement(const ScoreElement& se);
186
187 virtual ~ScoreElement();
188
score()189 Score* score() const { return _score; }
190 MasterScore* masterScore() const;
setScore(Score * s)191 virtual void setScore(Score* s) { _score = s; }
192 const char* name() const;
193 virtual QString userName() const;
194 virtual ElementType type() const = 0;
195
196 static ElementType name2type(const QStringRef&, bool silent = false);
name2type(const QString & s)197 static ElementType name2type(const QString& s) { return name2type(QStringRef(&s)); }
198 static const char* name(ElementType);
199
200 virtual QVariant getProperty(Pid) const = 0;
201 virtual bool setProperty(Pid, const QVariant&) = 0;
202 virtual QVariant propertyDefault(Pid) const;
203 virtual void resetProperty(Pid id);
204 QVariant propertyDefault(Pid pid, Tid tid) const;
sizeIsSpatiumDependent()205 virtual bool sizeIsSpatiumDependent() const { return true; }
offsetIsSpatiumDependent()206 virtual bool offsetIsSpatiumDependent() const { return true; }
207
208 virtual void reset(); // reset all properties & position to default
209
210 virtual Pid propertyId(const QStringRef& xmlName) const;
211 virtual QString propertyUserValue(Pid) const;
212
213 virtual void initElementStyle(const ElementStyle*);
styledProperties()214 virtual const ElementStyle* styledProperties() const { return _elementStyle; }
215
propertyFlagsList()216 virtual PropertyFlags* propertyFlagsList() const { return _propertyFlagsList; }
217 virtual PropertyFlags propertyFlags(Pid) const;
218 bool isStyled(Pid pid) const;
219 QVariant styleValue(Pid, Sid) const;
220
221 void setPropertyFlags(Pid, PropertyFlags);
222
223 virtual Sid getPropertyStyle(Pid) const;
224 bool readProperty(const QStringRef&, XmlReader&, Pid);
225 void readProperty(XmlReader&, Pid);
226 bool readStyledProperty(XmlReader& e, const QStringRef& tag);
227
228 virtual void readAddConnector(ConnectorInfoReader* info, bool pasteMode);
229
230 virtual void styleChanged();
231
232 virtual void undoChangeProperty(Pid id, const QVariant&, PropertyFlags ps);
233 void undoChangeProperty(Pid id, const QVariant&);
234 void undoResetProperty(Pid id);
235
236 void undoPushProperty(Pid);
237 void writeProperty(XmlWriter& xml, Pid id) const;
238 void writeStyledProperties(XmlWriter&) const;
239
240 QList<ScoreElement*> linkList() const;
241
242 void linkTo(ScoreElement*);
243 void unlink();
244 bool isLinked(ScoreElement*);
245
246 virtual void undoUnlink();
lid()247 int lid() const { return _links ? _links->lid() : 0; }
links()248 LinkedElements* links() const { return _links; }
setLinks(LinkedElements * le)249 void setLinks(LinkedElements* le) { _links = le; }
250
251 //---------------------------------------------------
252 // check type
253 //
254 // Example for ChordRest:
255 //
256 // bool isChordRest()
257 //---------------------------------------------------
258
259
260 #define CONVERT(a,b) \
261 bool is##a() const { return type() == ElementType::b; }
262
CONVERT(Note,NOTE)263 CONVERT(Note, NOTE)
264 CONVERT(Rest, REST)
265 CONVERT(Chord, CHORD)
266 CONVERT(BarLine, BAR_LINE)
267 CONVERT(Articulation, ARTICULATION)
268 CONVERT(Fermata, FERMATA)
269 CONVERT(Marker, MARKER)
270 CONVERT(Clef, CLEF)
271 CONVERT(KeySig, KEYSIG)
272 CONVERT(TimeSig, TIMESIG)
273 CONVERT(Measure, MEASURE)
274 CONVERT(TempoText, TEMPO_TEXT)
275 CONVERT(Breath, BREATH)
276 CONVERT(HBox, HBOX)
277 CONVERT(VBox, VBOX)
278 CONVERT(TBox, TBOX)
279 CONVERT(FBox, FBOX)
280 CONVERT(Tie, TIE)
281 CONVERT(Slur, SLUR)
282 CONVERT(Glissando, GLISSANDO)
283 CONVERT(GlissandoSegment, GLISSANDO_SEGMENT)
284 CONVERT(SystemDivider, SYSTEM_DIVIDER)
285 CONVERT(RehearsalMark, REHEARSAL_MARK)
286 CONVERT(Harmony, HARMONY)
287 CONVERT(Volta, VOLTA)
288 CONVERT(Jump, JUMP)
289 CONVERT(Ottava, OTTAVA)
290 CONVERT(LayoutBreak, LAYOUT_BREAK)
291 CONVERT(Segment, SEGMENT)
292 CONVERT(Tremolo, TREMOLO)
293 CONVERT(System, SYSTEM)
294 CONVERT(Lyrics, LYRICS)
295 CONVERT(Stem, STEM)
296 CONVERT(Beam, BEAM)
297 CONVERT(Hook, HOOK)
298 CONVERT(StemSlash, STEM_SLASH)
299 CONVERT(SlurSegment, SLUR_SEGMENT)
300 CONVERT(TieSegment, TIE_SEGMENT)
301 CONVERT(Spacer, SPACER)
302 CONVERT(StaffLines, STAFF_LINES)
303 CONVERT(Ambitus, AMBITUS)
304 CONVERT(Bracket, BRACKET)
305 CONVERT(InstrumentChange, INSTRUMENT_CHANGE)
306 CONVERT(StaffTypeChange, STAFFTYPE_CHANGE)
307 CONVERT(Hairpin, HAIRPIN)
308 CONVERT(HairpinSegment,HAIRPIN_SEGMENT)
309 CONVERT(Bend, BEND)
310 CONVERT(TremoloBar, TREMOLOBAR)
311 CONVERT(RepeatMeasure, REPEAT_MEASURE)
312 CONVERT(Tuplet, TUPLET)
313 CONVERT(NoteDot, NOTEDOT)
314 CONVERT(Dynamic, DYNAMIC)
315 CONVERT(InstrumentName, INSTRUMENT_NAME)
316 CONVERT(Accidental, ACCIDENTAL)
317 CONVERT(TextLine, TEXTLINE)
318 CONVERT(TextLineSegment, TEXTLINE_SEGMENT)
319 CONVERT(Pedal, PEDAL)
320 CONVERT(PedalSegment, PEDAL_SEGMENT)
321 CONVERT(OttavaSegment, OTTAVA_SEGMENT)
322 CONVERT(LedgerLine, LEDGER_LINE)
323 CONVERT(Icon, ICON)
324 CONVERT(VoltaSegment, VOLTA_SEGMENT)
325 CONVERT(NoteLine, NOTELINE)
326 CONVERT(Trill, TRILL)
327 CONVERT(TrillSegment, TRILL_SEGMENT)
328 CONVERT(LetRing, LET_RING)
329 CONVERT(LetRingSegment, LET_RING_SEGMENT)
330 CONVERT(Vibrato, VIBRATO)
331 CONVERT(PalmMute, PALM_MUTE)
332 CONVERT(PalmMuteSegment, PALM_MUTE_SEGMENT)
333 CONVERT(VibratoSegment, VIBRATO_SEGMENT)
334 CONVERT(Symbol, SYMBOL)
335 CONVERT(FSymbol, FSYMBOL)
336 CONVERT(Fingering, FINGERING)
337 CONVERT(NoteHead, NOTEHEAD)
338 CONVERT(LyricsLine, LYRICSLINE)
339 CONVERT(LyricsLineSegment, LYRICSLINE_SEGMENT)
340 CONVERT(FiguredBass, FIGURED_BASS)
341 CONVERT(StaffState, STAFF_STATE)
342 CONVERT(Arpeggio, ARPEGGIO)
343 CONVERT(Image, IMAGE)
344 CONVERT(ChordLine, CHORDLINE)
345 CONVERT(FretDiagram, FRET_DIAGRAM)
346 CONVERT(Page, PAGE)
347 CONVERT(Text, TEXT)
348 CONVERT(MeasureNumber, MEASURE_NUMBER)
349 CONVERT(MMRestRange, MMREST_RANGE)
350 CONVERT(StaffText, STAFF_TEXT)
351 CONVERT(SystemText, SYSTEM_TEXT)
352 CONVERT(BracketItem, BRACKET_ITEM)
353 CONVERT(Score, SCORE)
354 CONVERT(Staff, STAFF)
355 CONVERT(Part, PART)
356 CONVERT(BagpipeEmbellishment, BAGPIPE_EMBELLISHMENT)
357 CONVERT(Lasso, LASSO)
358 CONVERT(Sticking, STICKING)
359 #undef CONVERT
360
361 virtual bool isElement() const { return false; } // overridden in element.h
isChordRest()362 bool isChordRest() const { return isRest() || isChord() || isRepeatMeasure(); }
isDurationElement()363 bool isDurationElement() const { return isChordRest() || isTuplet(); }
isSlurTieSegment()364 bool isSlurTieSegment() const { return isSlurSegment() || isTieSegment(); }
365 bool isSLineSegment() const;
isBox()366 bool isBox() const { return isVBox() || isHBox() || isTBox() || isFBox(); }
isVBoxBase()367 bool isVBoxBase() const { return isVBox() || isTBox() || isFBox(); }
isMeasureBase()368 bool isMeasureBase() const { return isMeasure() || isBox(); }
369 bool isTextBase() const;
isTextLineBaseSegment()370 bool isTextLineBaseSegment() const {
371 return isHairpinSegment()
372 || isLetRingSegment()
373 || isTextLineSegment()
374 || isOttavaSegment()
375 || isPalmMuteSegment()
376 || isPedalSegment()
377 || isVoltaSegment()
378 ;
379 }
isLineSegment()380 bool isLineSegment() const {
381 return isGlissandoSegment()
382 || isLyricsLineSegment()
383 || isTextLineBaseSegment()
384 || isTrillSegment()
385 || isVibratoSegment()
386 ;
387 }
isSpannerSegment()388 bool isSpannerSegment() const { return isLineSegment() || isTextLineBaseSegment() || isSlurSegment() || isTieSegment(); }
isBSymbol()389 bool isBSymbol() const { return isImage() || isSymbol(); }
isTextLineBase()390 bool isTextLineBase() const {
391 return isHairpin()
392 || isLetRing()
393 || isNoteLine()
394 || isOttava()
395 || isPalmMute()
396 || isPedal()
397 || isTextLine()
398 || isVolta()
399 ;
400 }
isSLine()401 bool isSLine() const {
402 return isTextLineBase() || isTrill() || isGlissando() || isVibrato();
403 }
404
isSpanner()405 bool isSpanner() const {
406 return isSlur()
407 || isTie()
408 || isGlissando()
409 || isLyricsLine()
410 || isTextLineBase()
411 || isSLine()
412 ;
413 }
isStaffTextBase()414 bool isStaffTextBase() const {
415 return isStaffText() || isSystemText();
416 }
417 };
418
419 //---------------------------------------------------
420 // safe casting of ScoreElement
421 //
422 // Example for ChordRest:
423 //
424 // ChordRest* toChordRest(Element* e)
425 //---------------------------------------------------
426
toChordRest(ScoreElement * e)427 static inline ChordRest* toChordRest(ScoreElement* e) {
428 Q_ASSERT(e == 0 || e->type() == ElementType::CHORD || e->type() == ElementType::REST
429 || e->type() == ElementType::REPEAT_MEASURE);
430 return (ChordRest*)e;
431 }
toChordRest(const ScoreElement * e)432 static inline const ChordRest* toChordRest(const ScoreElement* e) {
433 Q_ASSERT(e == 0 || e->type() == ElementType::CHORD || e->type() == ElementType::REST
434 || e->type() == ElementType::REPEAT_MEASURE);
435 return (const ChordRest*)e;
436 }
toDurationElement(ScoreElement * e)437 static inline DurationElement* toDurationElement(ScoreElement* e) {
438 Q_ASSERT(e == 0 || e->type() == ElementType::CHORD || e->type() == ElementType::REST
439 || e->type() == ElementType::REPEAT_MEASURE || e->type() == ElementType::TUPLET);
440 return (DurationElement*)e;
441 }
toDurationElement(const ScoreElement * e)442 static inline const DurationElement* toDurationElement(const ScoreElement* e) {
443 Q_ASSERT(e == 0 || e->type() == ElementType::CHORD || e->type() == ElementType::REST
444 || e->type() == ElementType::REPEAT_MEASURE || e->type() == ElementType::TUPLET);
445 return (const DurationElement*)e;
446 }
toRest(ScoreElement * e)447 static inline Rest* toRest(ScoreElement* e) {
448 Q_ASSERT(!e || e->isRest() || e->isRepeatMeasure());
449 return (Rest*)e;
450 }
toRest(const ScoreElement * e)451 static inline const Rest* toRest(const ScoreElement* e) {
452 Q_ASSERT(!e || e->isRest() || e->isRepeatMeasure());
453 return (const Rest*)e;
454 }
toSlurTieSegment(ScoreElement * e)455 static inline SlurTieSegment* toSlurTieSegment(ScoreElement* e) {
456 Q_ASSERT(e == 0 || e->type() == ElementType::SLUR_SEGMENT || e->type() == ElementType::TIE_SEGMENT);
457 return (SlurTieSegment*)e;
458 }
toSlurTieSegment(const ScoreElement * e)459 static inline const SlurTieSegment* toSlurTieSegment(const ScoreElement* e) {
460 Q_ASSERT(e == 0 || e->type() == ElementType::SLUR_SEGMENT || e->type() == ElementType::TIE_SEGMENT);
461 return (const SlurTieSegment*)e;
462 }
toMeasureBase(const ScoreElement * e)463 static inline const MeasureBase* toMeasureBase(const ScoreElement* e) {
464 Q_ASSERT(e == 0 || e->isMeasure() || e->isVBox() || e->isHBox() || e->isTBox() || e->isFBox());
465 return (const MeasureBase*)e;
466 }
toMeasureBase(ScoreElement * e)467 static inline MeasureBase* toMeasureBase(ScoreElement* e) {
468 Q_ASSERT(e == 0 || e->isMeasureBase());
469 return (MeasureBase*)e;
470 }
toBox(ScoreElement * e)471 static inline Box* toBox(ScoreElement* e) {
472 Q_ASSERT(e == 0 || e->isBox());
473 return (Box*)e;
474 }
toSpannerSegment(ScoreElement * e)475 static inline SpannerSegment* toSpannerSegment(ScoreElement* e) {
476 Q_ASSERT(e == 0 || e->isSpannerSegment());
477 return (SpannerSegment*)e;
478 }
toSpannerSegment(const ScoreElement * e)479 static inline const SpannerSegment* toSpannerSegment(const ScoreElement* e) {
480 Q_ASSERT(e == 0 || e->isSpannerSegment());
481 return (const SpannerSegment*)e;
482 }
toBSymbol(ScoreElement * e)483 static inline BSymbol* toBSymbol(ScoreElement* e) {
484 Q_ASSERT(e == 0 || e->isBSymbol());
485 return (BSymbol*)e;
486 }
toTextLineBase(ScoreElement * e)487 static inline TextLineBase* toTextLineBase(ScoreElement* e) {
488 Q_ASSERT(e == 0 || e->isTextLineBase());
489 return (TextLineBase*)e;
490 }
toTextBase(ScoreElement * e)491 static inline TextBase* toTextBase(ScoreElement* e) {
492 Q_ASSERT(e == 0 || e->isTextBase());
493 return (TextBase*)e;
494 }
toTextBase(const ScoreElement * e)495 static inline const TextBase* toTextBase(const ScoreElement* e) {
496 Q_ASSERT(e == 0 || e->isTextBase());
497 return (const TextBase*)e;
498 }
toStaffTextBase(ScoreElement * e)499 static inline StaffTextBase* toStaffTextBase(ScoreElement* e) {
500 Q_ASSERT(e == 0 || e->isStaffTextBase());
501 return (StaffTextBase*)e;
502 }
toStaffTextBase(const ScoreElement * e)503 static inline const StaffTextBase* toStaffTextBase(const ScoreElement* e) {
504 Q_ASSERT(e == 0 || e->isStaffTextBase());
505 return (const StaffTextBase*)e;
506 }
507
508 #define CONVERT(a) \
509 static inline a* to##a(ScoreElement* e) { Q_ASSERT(e == 0 || e->is##a()); return (a*)e; } \
510 static inline const a* to##a(const ScoreElement* e) { Q_ASSERT(e == 0 || e->is##a()); return (const a*)e; }
511
512 CONVERT(Element)
513 CONVERT(Note)
514 CONVERT(Chord)
515 CONVERT(BarLine)
516 CONVERT(Articulation)
517 CONVERT(Fermata)
518 CONVERT(Marker)
519 CONVERT(Clef)
520 CONVERT(KeySig)
521 CONVERT(TimeSig)
522 CONVERT(Measure)
523 CONVERT(TempoText)
524 CONVERT(Breath)
525 CONVERT(HBox)
526 CONVERT(VBox)
527 CONVERT(TBox)
528 CONVERT(FBox)
529 CONVERT(Spanner)
530 CONVERT(Tie)
531 CONVERT(Slur)
532 CONVERT(Glissando)
533 CONVERT(GlissandoSegment)
534 CONVERT(SystemDivider)
535 CONVERT(RehearsalMark)
536 CONVERT(Harmony)
537 CONVERT(Volta)
538 CONVERT(Jump)
539 CONVERT(StaffText)
540 CONVERT(Ottava)
541 CONVERT(LayoutBreak)
542 CONVERT(Segment)
543 CONVERT(Tremolo)
544 CONVERT(System)
545 CONVERT(Lyrics)
546 CONVERT(Stem)
547 CONVERT(Beam)
548 CONVERT(Hook)
549 CONVERT(StemSlash)
550 CONVERT(LineSegment)
551 CONVERT(SlurSegment)
552 CONVERT(TieSegment)
553 CONVERT(Spacer)
554 CONVERT(StaffLines)
555 CONVERT(Ambitus)
556 CONVERT(Bracket)
557 CONVERT(InstrumentChange)
558 CONVERT(StaffTypeChange)
559 CONVERT(Text)
560 CONVERT(MeasureNumber)
561 CONVERT(MMRestRange)
562 CONVERT(Hairpin)
563 CONVERT(HairpinSegment)
564 CONVERT(Bend)
565 CONVERT(TremoloBar)
566 CONVERT(RepeatMeasure)
567 CONVERT(Tuplet)
568 CONVERT(NoteDot)
569 CONVERT(Dynamic)
570 CONVERT(InstrumentName)
571 CONVERT(Accidental)
572 CONVERT(TextLine)
573 CONVERT(TextLineSegment)
574 CONVERT(Pedal)
575 CONVERT(PedalSegment)
576 CONVERT(OttavaSegment)
577 CONVERT(LedgerLine)
578 CONVERT(Icon)
579 CONVERT(VoltaSegment)
580 CONVERT(NoteLine)
581 CONVERT(Trill)
582 CONVERT(TrillSegment)
583 CONVERT(LetRing)
584 CONVERT(LetRingSegment)
585 CONVERT(Vibrato)
586 CONVERT(VibratoSegment)
587 CONVERT(PalmMute)
588 CONVERT(PalmMuteSegment)
589 CONVERT(Symbol)
590 CONVERT(FSymbol)
591 CONVERT(Fingering)
592 CONVERT(NoteHead)
593 CONVERT(LyricsLine)
594 CONVERT(LyricsLineSegment)
595 CONVERT(FiguredBass)
596 CONVERT(StaffState)
597 CONVERT(Arpeggio)
598 CONVERT(Image)
599 CONVERT(ChordLine)
600 CONVERT(FretDiagram)
601 CONVERT(Page)
602 CONVERT(SystemText)
603 CONVERT(BracketItem)
604 CONVERT(Staff)
605 CONVERT(Part)
606 CONVERT(Lasso)
607 CONVERT(BagpipeEmbellishment)
608 CONVERT(Sticking)
609 #undef CONVERT
610
611 }
612
613 #endif
614