1 //=============================================================================
2 //  MuseScore
3 //  Music Composition & Notation
4 //
5 //  Copyright (C) 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 __CHORDLIST_H__
14 #define __CHORDLIST_H__
15 
16 namespace Ms {
17 
18 class XmlWriter;
19 class XmlReader;
20 class ChordList;
21 
22 //---------------------------------------------------------
23 //   class HDegree
24 //---------------------------------------------------------
25 
26 enum class HDegreeType : char {
27       UNDEF, ADD, ALTER, SUBTRACT
28       };
29 
30 class HDegree {
31       int _value;
32       int _alter;       // -1, 0, 1  (b - - #)
33       HDegreeType _type;
34 
35    public:
HDegree()36       HDegree() { _value = 0; _alter = 0; _type = HDegreeType::UNDEF; }
HDegree(int v,int a,HDegreeType t)37       HDegree(int v, int a, HDegreeType t) { _value = v; _alter = a; _type = t; }
value()38       int value() const { return _value; }
alter()39       int alter() const { return _alter; }
type()40       HDegreeType type() const  { return _type; }
41       QString text() const;
42       };
43 
44 //---------------------------------------------------------
45 //   HChord
46 //---------------------------------------------------------
47 
48 class HChord {
49       QString str;
50 
51    protected:
52       int keys;
53 
54    public:
HChord()55       HChord()      { keys = 0; }
HChord(int k)56       HChord(int k) { keys = k; }
57       HChord(int a, int b, int c=-1, int d=-1, int e=-1, int f=-1, int g=-1,
58             int h=-1, int i=-1, int k=-1, int l=-1);
59       HChord(const QString&);
60 
61       void rotate(int semiTones);
62 
contains(int key)63       bool contains(int key) const {       // key in chord?
64             return (1 << (key % 12)) & keys;
65             }
66       HChord& operator+= (int key) {
67             keys |= (1 << (key % 12));
68             return *this;
69             }
70       HChord& operator-= (int key) {
71             keys &= ~(1 << (key % 12));
72             return *this;
73             }
74       bool operator==(const HChord& o) const { return (keys == o.keys); }
75       bool operator!=(const HChord& o) const { return (keys != o.keys); }
76 
getKeys()77       int getKeys() const { return keys; }
78       void print() const;
79 
80       QString name(int tpc) const;
81       QString voicing() const;
82       void add(const QList<HDegree>& degreeList);
83       };
84 
85 //---------------------------------------------------------
86 //   RenderAction
87 //---------------------------------------------------------
88 
89 struct RenderAction {
90       enum class RenderActionType : char {
91             SET, MOVE, PUSH, POP,
92             NOTE, ACCIDENTAL
93             };
94 
95       RenderActionType type;
96       qreal movex, movey;          // MOVE
97       QString text;                 // SET
98 
RenderActionRenderAction99       RenderAction() {}
RenderActionRenderAction100       RenderAction(RenderActionType t) : type(t) {}
101       void print() const;
102       };
103 
104 //---------------------------------------------------------
105 //   ChordToken
106 //---------------------------------------------------------
107 
108 enum class ChordTokenClass : char {
109       ALL, QUALITY, EXTENSION, MODIFIER, ALTERATION, ADJUST, MODE, SUSPENSION, ADDITION, SUBTRACTION
110       };
111 
112 class ChordToken {
113    public:
114       ChordTokenClass tokenClass;
115       QStringList names;
116       QList<RenderAction> renderList;
117       void read(XmlReader&);
118       void write(XmlWriter&) const;
119       };
120 
121 //---------------------------------------------------------
122 //   ParsedChord
123 //---------------------------------------------------------
124 
125 class ParsedChord {
126    public:
127       bool parse(const QString&, const ChordList*, bool syntaxOnly = false, bool preferMinor = false);
128       QString fromXml(const QString&, const QString&, const QString&, const QString&, const QList<HDegree>&, const ChordList*);
129       const QList<RenderAction>& renderList(const ChordList*);
parseable()130       bool parseable() const                    { return _parseable; }
understandable()131       bool understandable() const               { return _understandable; }
name()132       const QString& name() const               { return _name; }
quality()133       const QString& quality() const            { return _quality; }
extension()134       const QString& extension() const          { return _extension; }
modifiers()135       const QString& modifiers() const          { return _modifiers; }
modifierList()136       const QStringList& modifierList() const   { return _modifierList; }
xmlKind()137       const QString& xmlKind() const            { return _xmlKind; }
xmlText()138       const QString& xmlText() const            { return _xmlText; }
xmlSymbols()139       const QString& xmlSymbols() const         { return _xmlSymbols; }
xmlParens()140       const QString& xmlParens() const          { return _xmlParens; }
xmlDegrees()141       const QStringList& xmlDegrees() const     { return _xmlDegrees; }
keys()142       int keys() const                          { return chord.getKeys(); }
handle()143       const QString& handle() const             { return _handle; }
QString()144       operator QString() const                  { return _handle; }
145       bool operator==(const ParsedChord& c) const     { return (this->_handle == c._handle); }
146       bool operator!=(const ParsedChord& c) const     { return !(*this == c); }
147       ParsedChord();
148    private:
149       QString _name;
150       QString _handle;
151       QString _quality;
152       QString _extension;
153       QString _modifiers;
154       QStringList _modifierList;
155       QList<ChordToken> _tokenList;
156       QList<RenderAction> _renderList;
157       QString _xmlKind;
158       QString _xmlText;
159       QString _xmlSymbols;
160       QString _xmlParens;
161       QStringList _xmlDegrees;
162       QStringList major, minor, diminished, augmented, lower, raise, mod1, mod2, symbols;
163       HChord chord;
164       bool _parseable;
165       bool _understandable;
166       void configure(const ChordList*);
167       void correctXmlText(const QString& s = "");
168       void addToken(QString, ChordTokenClass);
169       };
170 
171 //---------------------------------------------------------
172 //   ChordDescription
173 //---------------------------------------------------------
174 
175 struct ChordDescription {
176       int id;                 // Chord id number (Band In A Box Chord Number)
177       QStringList names;      // list of alternative chord names
178                               // that will by recognized from keyboard entry (without root/base)
179       QList<ParsedChord> parsedChords;
180                               // parsed forms of primary name (optionally also include parsed forms of other names)
181       QString xmlKind;        // MusicXml: kind
182       QString xmlText;        // MusicXml: kind text=
183       QString xmlSymbols;     // MusicXml: kind use-symbols=
184       QString xmlParens;      // MusicXml: kind parentheses-degrees=
185       QStringList xmlDegrees; // MusicXml: list of degrees (if any)
186       HChord chord;           // C based chord
187       QList<RenderAction> renderList;
188       bool generated;
189       bool renderListGenerated;
190       bool exportOk;
191       QString _quality;
192 
193    public:
ChordDescriptionChordDescription194       ChordDescription() {}
195       ChordDescription(int);
196       ChordDescription(const QString&);
qualityChordDescription197       QString quality() const       { return _quality; }
198       void complete(ParsedChord* pc, const ChordList*);
199       void read(XmlReader&);
200       void write(XmlWriter&) const;
201       };
202 
203 //---------------------------------------------------------
204 //   ChordSymbol
205 //---------------------------------------------------------
206 
207 struct ChordSymbol {
208       int fontIdx;
209       QString name;
210       QString value;
211       QChar code;
212 
ChordSymbolChordSymbol213       ChordSymbol() { fontIdx = -1; }
isValidChordSymbol214       bool isValid() const { return fontIdx != -1; }
215       };
216 
217 //---------------------------------------------------------
218 //   ChordFont
219 //---------------------------------------------------------
220 
221 struct ChordFont {
222       QString family;
223       QString fontClass;
224       qreal mag;
225       };
226 
227 //---------------------------------------------------------
228 //   ChordList
229 //---------------------------------------------------------
230 
231 class ChordList : public QMap<int, ChordDescription> {
232       QMap<QString, ChordSymbol> symbols;
233       bool _autoAdjust = false;
234       qreal _nmag = 1.0, _nadjust = 0.0;
235       qreal _emag = 1.0, _eadjust = 0.0;
236       qreal _mmag = 1.0, _madjust = 0.0;
237 
238    public:
239       QList<ChordFont> fonts;
240       QList<RenderAction> renderListRoot;
241       QList<RenderAction> renderListFunction;
242       QList<RenderAction> renderListBase;
243       QList<ChordToken> chordTokenList;
244       static int privateID;
245 
autoAdjust()246       bool autoAdjust() const                   { return _autoAdjust;   }
nominalMag()247       qreal nominalMag() const                  { return _nmag;         }
nominalAdjust()248       qreal nominalAdjust() const               { return _nadjust;      }
249       void configureAutoAdjust(qreal emag = 1.0, qreal eadjust = 0.0, qreal mmag = 1.0, qreal madjust = 0.0);
250       qreal position(const QStringList& names, ChordTokenClass ctc) const;
251 
252       void write(XmlWriter& xml) const;
253       void read(XmlReader&);
254       bool read(const QString&);
255       bool write(const QString&) const;
256       bool loaded() const;
257       void unload();
symbol(const QString & s)258       ChordSymbol symbol(const QString& s) const { return symbols.value(s); }
259       };
260 
261 
262 }     // namespace Ms
263 #endif
264 
265