d11f1b118b
- Measure: -- firstSegment -- lastSegment - MeasureBase: -- nextMeasure -- nextMeasureMM (new) -- prevMeasure -- prevMeasureMM (new) - Score: -- firstMeasure -- firstMeasureMM (new) -- (for firstSegment(), see special cases below) -- lastMeasure -- lastMeasureMM (new) -- lastSegment - Segment: -- next (renamed from `next1`) -- nextInMeasure (renamed from `next`) -- prev (renamed from `prev1`) -- prevInMeasure (renamed from prev) Special cases: - Cursor: The prototype of the `Q_INVOKABLE Ms::Note* Cursor::addNote(int pitch)` was wrong: corrected in `Q_INVOKABLE void Cursor::addNote(int pitch)`. - QmlPlugin: `Q_INVOKABLE Score* QmlPlugin::readScore()` and `Q_INVOKABLE Score* QmlPlugin::newScore()` has been kept, as they are intended to be called from QML; code has been added to ensure the C++ ownership of the returned object. - Score: `Q_INVOKABLE Segment* Score::firstSegment(Segment::Type segType)` is kept (as it needs a parameters), but code is added to ensure C++ ownership of the returned Segment*. - Segment: `Ms::Element* Segment::element(int track)` has been made NOT Q_INVOKABLE; a variant `Q_INVOKABLE Ms::Element* elementAt(int track)` has been added specifically for QML with code to ensure the C++ ownership of the returned Element* (this was the cause for the crash of the Walk plug-in). - FiguredBass: `Q_INVOKABLE Ms::FiguredBassItem* FiguredBass::addItem()` has been removed; plugin interface for FiguredBass needs to be redesigned anyway. The few occurrences in the supplied plug-ins of the methods whose names did change have been updated.
339 lines
17 KiB
C++
339 lines
17 KiB
C++
//=============================================================================
|
|
// MuseScore
|
|
// Music Composition & Notation
|
|
//
|
|
// Copyright (C) 2002-2011 Werner Schweer
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License version 2
|
|
// as published by the Free Software Foundation and appearing in
|
|
// the file LICENCE.GPL
|
|
//=============================================================================
|
|
|
|
#ifndef __FIGUREDBASS_H__
|
|
#define __FIGUREDBASS_H__
|
|
|
|
#include "segment.h"
|
|
#include "text.h"
|
|
//#include "libmscore/figuredbass.h"
|
|
#include <vector>
|
|
|
|
namespace Ms {
|
|
|
|
/*---------------------------------------------------------
|
|
NOTE ON ARCHITECTURE
|
|
|
|
FiguredBass elements are stored in the annotations of a Segment (like for instance Harmony)
|
|
|
|
FiguredBass is rather simple: it contains only _ticks, telling the duration of the element,
|
|
and a list of FiguredBassItem elements which do most of the job. It also maintains a text with the
|
|
normalized (made uniform) version of the text, which is used during editing.
|
|
|
|
Normally, a FiguredBass element is assumed to be styled with an internally maintained text style
|
|
(based on the parameters of the general style "Figured Bass") FIGURED_BASS style and it is set
|
|
in this way upon creation and upon layout().
|
|
- - - -
|
|
FiguredBassItem contains the actually f.b. info; it is made of 4 parts (in this order):
|
|
1) prefix: one of [nothing, doubleflat, flat, natural, sharp, doublesharp, cross]
|
|
2) digit: one digit from 1 to 9
|
|
3) suffix: one of [nothing, doubleflat, flat, natural, sharp, doublesharp, cross, backslash, slash]
|
|
4) contLine: true if the item has a continuation line (whose length is determined by parent's _ticks)
|
|
and 5 parenthesis flags, one for each position before, between and after the four parts above:
|
|
each of them may contain one of [nothing, roundOpen, roundClosed, squaredOpen, squaredClosed].
|
|
|
|
There is a number of restrictions, implemented at the end of FiguredBassItem::parse().
|
|
Currently, no attempt is made to ensure that, if multiple parentheses are present, they are consistent
|
|
(matching open and closed parentheses is left to the user).
|
|
|
|
If an item cannot be parsed, the whole FiguredBass element is kept as entered, possibly un-styled.
|
|
If all items can be parsed, each item generates a display text from its properties,
|
|
lays it out so that it properly aligns under the chord, draws it at its proper location
|
|
and provides its FiguredBass parent with a normalized text for future editing.
|
|
|
|
FiguredBassItem has not use for formats (italics, bold, ...) and it is never edited directly;
|
|
more generally, it is never accessed directly, only via its FiguredBass parent;
|
|
so it is directly derived from Element and returns INVALID as type.
|
|
|
|
FiguredBass might require formatting (discouraged, but might be necessary for very uncommon cases)
|
|
and it is edited (via the normalized text); so it is derived from Text.
|
|
---------------------------------------------------------*/
|
|
|
|
#define FBIDigitNone -1
|
|
|
|
//---------------------------------------------------------
|
|
// @@ FiguredBassItem
|
|
/// One line of a figured bass indication
|
|
//
|
|
// @P prefix Ms::FiguredBassItem::Modifier (NONE, DOUBLEFLAT, FLAT, NATURAL, SHARP, DOUBLESHARP, PLUS, BACKSLASH, SLASH, NUMOF) accidental before the digit
|
|
// @P digit int main digit (0 - 9)
|
|
// @P suffix Ms::FiguredBassItem::Modifier (NONE, DOUBLEFLAT, FLAT, NATURAL, SHARP, DOUBLESHARP, PLUS, BACKSLASH, SLASH, NUMOF) accidental/diacritic after the digit
|
|
// @P continuationLine MS::FiguredBassItem::ContLine (NONE, SIMPLE, EXTENDED) whether item has continuation line or not, and which
|
|
// @P parenthesis1 Ms::FiguredBassItem::Parenthesis (NONE, ROUNDOPEN, ROUNDCLOSED, SQUAREDOPEN, SQUAREDCLOSED) parentesis before the prefix
|
|
// @P parenthesis2 Ms::FiguredBassItem::Parenthesis (NONE, ROUNDOPEN, ROUNDCLOSED, SQUAREDOPEN, SQUAREDCLOSED) parentesis after the prefix / before the digit
|
|
// @P parenthesis3 Ms::FiguredBassItem::Parenthesis (NONE, ROUNDOPEN, ROUNDCLOSED, SQUAREDOPEN, SQUAREDCLOSED) parentesis after the digit / before the suffix
|
|
// @P parenthesis4 Ms::FiguredBassItem::Parenthesis (NONE, ROUNDOPEN, ROUNDCLOSED, SQUAREDOPEN, SQUAREDCLOSED) parentesis after the suffix / before the cont. line
|
|
// @P parenthesis5 Ms::FiguredBassItem::Parenthesis (NONE, ROUNDOPEN, ROUNDCLOSED, SQUAREDOPEN, SQUAREDCLOSED) parentesis after the cont. line
|
|
// @P displayText QString text displayed (depends on configured fonts) (read only)
|
|
// @P normalizedText Qstring conventional textual representation of item properties (= text used during input) (read ony)
|
|
//---------------------------------------------------------
|
|
|
|
class FiguredBass;
|
|
|
|
class FiguredBassItem : public Element {
|
|
Q_OBJECT
|
|
Q_ENUMS(Modifier)
|
|
Q_ENUMS(Parenthesis)
|
|
Q_ENUMS(ContLine)
|
|
Q_PROPERTY(Ms::FiguredBassItem::Modifier prefix READ prefix WRITE undoSetPrefix)
|
|
Q_PROPERTY(int digit READ digit WRITE undoSetDigit)
|
|
Q_PROPERTY(Ms::FiguredBassItem::Modifier suffix READ suffix WRITE undoSetSuffix)
|
|
Q_PROPERTY(Ms::FiguredBassItem::ContLine continuationLine READ contLine WRITE undoSetContLine)
|
|
Q_PROPERTY(Ms::FiguredBassItem::Parenthesis parenthesis1 READ parenth1 WRITE undoSetParenth1)
|
|
Q_PROPERTY(Ms::FiguredBassItem::Parenthesis parenthesis2 READ parenth2 WRITE undoSetParenth2)
|
|
Q_PROPERTY(Ms::FiguredBassItem::Parenthesis parenthesis3 READ parenth3 WRITE undoSetParenth3)
|
|
Q_PROPERTY(Ms::FiguredBassItem::Parenthesis parenthesis4 READ parenth4 WRITE undoSetParenth4)
|
|
Q_PROPERTY(Ms::FiguredBassItem::Parenthesis parenthesis5 READ parenth5 WRITE undoSetParenth5)
|
|
Q_PROPERTY(QString displayText READ displayText)
|
|
Q_PROPERTY(QString normalizedText READ normalizedText)
|
|
|
|
public:
|
|
enum class Modifier : char {
|
|
NONE = 0,
|
|
DOUBLEFLAT,
|
|
FLAT,
|
|
NATURAL,
|
|
SHARP,
|
|
DOUBLESHARP,
|
|
CROSS,
|
|
BACKSLASH,
|
|
SLASH,
|
|
NUMOF
|
|
};
|
|
enum class Parenthesis : char {
|
|
NONE = 0,
|
|
ROUNDOPEN,
|
|
ROUNDCLOSED,
|
|
SQUAREDOPEN,
|
|
SQUAREDCLOSED,
|
|
NUMOF
|
|
};
|
|
enum class ContLine : char {
|
|
NONE = 0,
|
|
SIMPLE, // cont. line stops at f.b. element end
|
|
EXTENDED // cont. line joins with next element, if possible
|
|
};
|
|
|
|
enum class Style : char {
|
|
MODERN = 0,
|
|
HISTORIC,
|
|
NUMOF
|
|
};
|
|
enum class Combination : char {
|
|
SIMPLE = 0,
|
|
CROSSED,
|
|
BACKSLASHED,
|
|
SLASHED,
|
|
NUMOF
|
|
};
|
|
|
|
private:
|
|
|
|
static const QChar normParenthToChar[int(Parenthesis::NUMOF)];
|
|
|
|
QString _displayText; // the constructed display text (read-only)
|
|
int ord; // the line ordinal of this element in the FB stack
|
|
// the parts making a FiguredBassItem up
|
|
Modifier _prefix; // the accidental coming before the body
|
|
int _digit; // the main digit (if present)
|
|
Modifier _suffix; // the accidental coming after the body
|
|
ContLine _contLine; // whether the item has continuation line or not
|
|
Parenthesis parenth[5]; // each of the parenthesis: before, between and after parts
|
|
qreal textWidth; // the text width (in raster units), set during layout()
|
|
// used by draw()
|
|
// part parsing
|
|
int parseDigit(QString& str);
|
|
int parseParenthesis(QString& str, int parenthIdx);
|
|
int parsePrefixSuffix(QString& str, bool bPrefix);
|
|
|
|
void setDisplayText(const QString& s) { _displayText = s; }
|
|
// read / write MusicXML support
|
|
QString Modifier2MusicXML(FiguredBassItem::Modifier prefix) const;
|
|
|
|
public:
|
|
FiguredBassItem(Score * s = 0, int line = 0);
|
|
FiguredBassItem(const FiguredBassItem&);
|
|
~FiguredBassItem();
|
|
|
|
FiguredBassItem &operator=(const FiguredBassItem&) = delete;
|
|
|
|
FiguredBassItem::Modifier MusicXML2Modifier(const QString prefix) const;
|
|
|
|
// standard re-implemented virtual functions
|
|
virtual FiguredBassItem* clone() const { return new FiguredBassItem(*this); }
|
|
virtual Element::Type type() const { return Element::Type::INVALID; }
|
|
virtual void draw(QPainter* painter) const;
|
|
virtual void layout();
|
|
virtual void read(XmlReader&);
|
|
virtual void write(Xml& xml) const;
|
|
|
|
// read / write MusicXML
|
|
// void readMusicXML(XmlReader& de, bool paren, bool& extend);
|
|
void writeMusicXML(Xml& xml, bool doFigure, bool doExtend) const;
|
|
bool startsWithParenthesis() const;
|
|
|
|
// specific API
|
|
const FiguredBass * figuredBass() const { return (FiguredBass*)(parent()); }
|
|
bool parse(QString& text);
|
|
|
|
// getters / setters
|
|
Modifier prefix() const { return _prefix; }
|
|
void setPrefix(const Modifier& v) { _prefix = v; }
|
|
void undoSetPrefix(Modifier pref);
|
|
int digit() const { return _digit; }
|
|
void setDigit(int val) { _digit = val; }
|
|
void undoSetDigit(int digit);
|
|
Modifier suffix() const { return _suffix; }
|
|
void setSuffix(const Modifier& v) { _suffix = v; }
|
|
void undoSetSuffix(Modifier suff);
|
|
ContLine contLine() const { return _contLine; }
|
|
void undoSetContLine(ContLine val);
|
|
Parenthesis parenth1() { return parenth[0]; }
|
|
Parenthesis parenth2() { return parenth[1]; }
|
|
Parenthesis parenth3() { return parenth[2]; }
|
|
Parenthesis parenth4() { return parenth[3]; }
|
|
Parenthesis parenth5() { return parenth[4]; }
|
|
|
|
void setParenth1(Parenthesis v) { parenth[0] = v; }
|
|
void setParenth2(Parenthesis v) { parenth[1] = v; }
|
|
void setParenth3(Parenthesis v) { parenth[2] = v; }
|
|
void setParenth4(Parenthesis v) { parenth[3] = v; }
|
|
void setParenth5(Parenthesis v) { parenth[4] = v; }
|
|
|
|
void undoSetParenth1(Parenthesis par);
|
|
void undoSetParenth2(Parenthesis par);
|
|
void undoSetParenth3(Parenthesis par);
|
|
void undoSetParenth4(Parenthesis par);
|
|
void undoSetParenth5(Parenthesis par);
|
|
QString normalizedText() const;
|
|
QString displayText() const { return _displayText; }
|
|
|
|
virtual QVariant getProperty(P_ID propertyId) const;
|
|
virtual bool setProperty(P_ID propertyId, const QVariant&);
|
|
virtual QVariant propertyDefault(P_ID) const;
|
|
};
|
|
|
|
//---------------------------------------------------------
|
|
// FiguredBassFont
|
|
//---------------------------------------------------------
|
|
|
|
struct FiguredBassFont {
|
|
QString family;
|
|
QString displayName;
|
|
qreal defPitch;
|
|
qreal defLineHeight;
|
|
QChar displayAccidental[int(FiguredBassItem::Modifier::NUMOF)];
|
|
QChar displayParenthesis[int(FiguredBassItem::Parenthesis::NUMOF)];
|
|
QChar displayDigit[int(FiguredBassItem::Style::NUMOF)][10][int(FiguredBassItem::Combination::NUMOF)];
|
|
|
|
bool read(XmlReader&);
|
|
};
|
|
|
|
//---------------------------------------------------------
|
|
// @@ FiguredBass
|
|
/// A complete figured bass indication
|
|
//
|
|
// @P onNote bool whether it is placed on a note beginning or between notes (read only)
|
|
// @P ticks int duration in ticks
|
|
//---------------------------------------------------------
|
|
|
|
class FiguredBass : public Text {
|
|
Q_OBJECT
|
|
|
|
// Q_PROPERTY(QDeclarativeListProperty<FiguredBassItem> items READ qmlItems)
|
|
Q_PROPERTY(bool onNote READ onNote)
|
|
Q_PROPERTY(int ticks READ ticks WRITE setTicks)
|
|
|
|
std::vector<FiguredBassItem*> items; // the individual lines of the F.B.
|
|
QVector<qreal> _lineLenghts; // lengths of duration indicator lines (in raster units)
|
|
bool _onNote; // true if this element is on a staff note | false if it is betweee notes
|
|
int _ticks; // the duration (used for cont. lines and for multiple F.B.
|
|
// under the same note)
|
|
qreal _printedLineLength; // the length of lines actually printed (i.e. continuation lines)
|
|
void layoutLines();
|
|
bool hasParentheses() const; // read / write MusicXML support
|
|
|
|
public:
|
|
FiguredBass(Score* s = 0);
|
|
FiguredBass(const FiguredBass&);
|
|
~FiguredBass();
|
|
|
|
// a convenience static function to create/retrieve a new FiguredBass into/from its intended parent
|
|
static FiguredBass * addFiguredBassToSegment(Segment *seg, int track, int extTicks, bool *pNew);
|
|
|
|
// static functions for font config files
|
|
static bool readConfigFile(const QString& fileName);
|
|
static QList<QString> fontNames();
|
|
static bool fontData(int nIdx, QString *pFamily, QString *pDisplayName,
|
|
qreal * pSize, qreal * pLineHeight);
|
|
|
|
// standard re-implemented virtual functions
|
|
virtual FiguredBass* clone() const { return new FiguredBass(*this); }
|
|
virtual Element::Type type() const { return Element::Type::FIGURED_BASS; }
|
|
virtual void draw(QPainter* painter) const;
|
|
// virtual bool edit(MuseScoreView*msv, int currGrip, int key, Qt::KeyboardModifiers modifiers, const QString& _s);
|
|
virtual void endEdit();
|
|
virtual void layout();
|
|
virtual void read(XmlReader&);
|
|
virtual void setSelected(bool f);
|
|
virtual void setVisible(bool f);
|
|
virtual void startEdit(MuseScoreView *msv, const QPointF &pt);
|
|
virtual void write(Xml& xml) const;
|
|
|
|
// read / write MusicXML
|
|
bool readMusicXML(XmlReader& de, int divisions, bool& extend);
|
|
void writeMusicXML(Xml& xml, bool doFigure, bool doExtend) const;
|
|
|
|
//DEBUG
|
|
//Q_INVOKABLE Ms::FiguredBassItem* addItem();
|
|
|
|
// getters / setters / properties
|
|
// void qmlItemsAppend(QDeclarativeListProperty<FiguredBassItem> *list, FiguredBassItem * pItem)
|
|
// { list->append(pItem);
|
|
// items.append(&pItem);
|
|
// }
|
|
// QDeclarativeListProperty<FiguredBassItem> qmlItems()
|
|
// { QList<FiguredBassItem*> list;
|
|
// foreach(FiguredBassItem item, items)
|
|
// list.append(&item);
|
|
// return QDeclarativeListProperty<FiguredBassItem>(this, &items, qmlItemsAppend);
|
|
// }
|
|
qreal lineLength(int idx) const { if(_lineLenghts.size() > idx)
|
|
return _lineLenghts.at(idx);
|
|
return 0; }
|
|
qreal printedLineLength() const { return _printedLineLength; }
|
|
bool onNote() const { return _onNote; }
|
|
int numOfItems() const { return items.size(); }
|
|
void setOnNote(bool val) { _onNote = val; }
|
|
Segment * segment() const { return static_cast<Segment*>(parent()); }
|
|
int ticks() const { return _ticks; }
|
|
void setTicks(int val) { _ticks = val; }
|
|
|
|
qreal additionalContLineX(qreal pagePosY) const;// returns the X coord (in page coord) of cont. line at pagePosY, if any
|
|
FiguredBass * nextFiguredBass() const; // returns next *adjacent* f.b. item, if any
|
|
|
|
virtual QVariant getProperty(P_ID propertyId) const;
|
|
virtual bool setProperty(P_ID propertyId, const QVariant&);
|
|
virtual QVariant propertyDefault(P_ID) const;
|
|
|
|
void appendItem(FiguredBassItem* item) { items.push_back(item); }
|
|
};
|
|
|
|
|
|
} // namespace Ms
|
|
|
|
Q_DECLARE_METATYPE(Ms::FiguredBassItem::Modifier);
|
|
Q_DECLARE_METATYPE(Ms::FiguredBassItem::Parenthesis);
|
|
Q_DECLARE_METATYPE(Ms::FiguredBassItem::ContLine);
|
|
|
|
#endif
|
|
|