2012-05-26 14:26:10 +02:00
//=============================================================================
// 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"
2013-01-17 11:33:11 +01:00
# include "libmscore/figuredbass.h"
2012-05-26 14:26:10 +02:00
2013-05-13 18:49:17 +02:00
namespace Ms {
2012-05-26 14:26:10 +02:00
/*---------------------------------------------------------
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 .
2012-08-14 14:58:43 +02:00
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 ( ) .
2012-05-26 14:26:10 +02:00
- - - -
FiguredBassItem contains the actually f . b . info ; it is made of 4 parts ( in this order ) :
2013-02-10 07:01:31 +01:00
1 ) prefix : one of [ nothing , doubleflat , flat , natural , sharp , doublesharp , cross ]
2012-05-26 14:26:10 +02:00
2 ) digit : one digit from 1 to 9
2013-02-10 07:01:31 +01:00
3 ) suffix : one of [ nothing , doubleflat , flat , natural , sharp , doublesharp , cross , backslash , slash ]
2012-05-26 14:26:10 +02:00
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 ;
2012-08-01 19:06:20 +02:00
so it is directly derived from Element and returns INVALID as type .
2012-05-26 14:26:10 +02:00
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 .
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2013-02-10 07:01:31 +01:00
# define FBIDigitNone -1
2013-01-17 11:33:11 +01:00
2012-05-26 14:26:10 +02:00
//---------------------------------------------------------
2012-07-25 11:49:34 +02:00
// @@ FiguredBassItem
2012-08-10 20:50:27 +02:00
/// One line of a figured bass indication
//
2012-08-14 14:58:43 +02:00
// @P prefix enum FiguredBassItem.ModifierNone, .ModifierDoubleFlat, .ModifierFlat, .ModifierNatural, .ModifierSharp, .ModifierDoubleSharp the accidental before the digit
2012-08-10 20:50:27 +02:00
// @P digit int the main digit (0 - 9)
2012-08-14 14:58:43 +02:00
// @P suffix enum FiguredBassItem.ModifierNone, .ModifierDoubleFlat, .ModifierFlat, .ModifierNatural, .ModifierSharp, .ModifierDoubleSharp, .ModifierPlus, .ModifierBackslash, .ModifierSlash the accidental/diacritic after the digit
2012-08-10 20:50:27 +02:00
// @P continuationLine bool whether the item has a continuation line or not
2012-08-14 14:58:43 +02:00
// @P parenthesis1 enum FiguredBassItem.ParenthesisNone, .ParenthesisRoundOpen, ParenthesisRoundClosed, ParenthesisSquaredOpen, ParenthesisSquaredClosed the parentesis before the prefix
// @P parenthesis2 enum FiguredBassItem.ParenthesisNone, .ParenthesisRoundOpen, ParenthesisRoundClosed, ParenthesisSquaredOpen, ParenthesisSquaredClosed the parentesis after the prefix / before the digit
// @P parenthesis3 enum FiguredBassItem.ParenthesisNone, .ParenthesisRoundOpen, ParenthesisRoundClosed, ParenthesisSquaredOpen, ParenthesisSquaredClosed the parentesis after the digit / before the suffix
// @P parenthesis4 enum FiguredBassItem.ParenthesisNone, .ParenthesisRoundOpen, ParenthesisRoundClosed, ParenthesisSquaredOpen, ParenthesisSquaredClosed the parentesis after the suffix / before the cont. line
// @P parenthesis5 enum FiguredBassItem.ParenthesisNone, .ParenthesisRoundOpen, ParenthesisRoundClosed, ParenthesisSquaredOpen, ParenthesisSquaredClosed the parentesis after the cont. line
2012-08-10 20:50:27 +02:00
// @P displayText string R/O the text displayed (depends on configured fonts)
// @P normalizedText string R/O conventional textual representation of item properties (= text used during input)
2012-05-26 14:26:10 +02:00
//---------------------------------------------------------
class FiguredBass ;
2012-08-01 19:06:20 +02:00
class FiguredBassItem : public Element {
2012-05-28 11:29:21 +02:00
Q_OBJECT
2012-08-14 14:58:43 +02:00
Q_ENUMS ( Modifier )
Q_ENUMS ( Parenthesis )
Q_PROPERTY ( Modifier prefix READ prefix WRITE undoSetPrefix )
Q_PROPERTY ( int digit READ digit WRITE undoSetDigit )
Q_PROPERTY ( Modifier suffix READ suffix WRITE undoSetSuffix )
2013-02-12 16:00:05 +01:00
Q_PROPERTY ( ContLine continuationLine READ contLine WRITE undoSetContLine )
2012-08-14 14:58:43 +02:00
Q_PROPERTY ( Parenthesis parenthesis1 READ parenth1 WRITE undoSetParenth1 )
Q_PROPERTY ( Parenthesis parenthesis2 READ parenth2 WRITE undoSetParenth2 )
Q_PROPERTY ( Parenthesis parenthesis3 READ parenth3 WRITE undoSetParenth3 )
Q_PROPERTY ( Parenthesis parenthesis4 READ parenth4 WRITE undoSetParenth4 )
Q_PROPERTY ( Parenthesis parenthesis5 READ parenth5 WRITE undoSetParenth5 )
Q_PROPERTY ( QString displayText READ displayText )
Q_PROPERTY ( QString normalizedText READ normalizedText )
2012-05-26 14:26:10 +02:00
2012-08-10 20:50:27 +02:00
public :
2012-08-11 01:15:22 +02:00
enum Modifier {
ModifierNone = 0 ,
ModifierDoubleFlat ,
ModifierFlat ,
ModifierNatural ,
ModifierSharp ,
ModifierDoubleSharp ,
2013-02-10 07:01:31 +01:00
ModifierCross ,
2012-08-11 01:15:22 +02:00
ModifierBackslash ,
ModifierSlash ,
NumOfModifiers
2012-05-26 14:26:10 +02:00
} ;
2012-08-11 01:15:22 +02:00
enum Parenthesis {
ParenthesisNone = 0 ,
ParenthesisRoundOpen ,
ParenthesisRoundClosed ,
ParenthesisSquaredOpen ,
ParenthesisSquaredClosed ,
NumOfParentheses
2012-05-26 14:26:10 +02:00
} ;
2013-02-12 16:00:05 +01:00
enum ContLine {
ContLineNone = 0 ,
ContLineSimple , // cont. line stops at f.b. element end
ContLineExtended // cont. line joins with next element, if possible
} ;
2013-02-10 07:01:31 +01:00
enum Styles {
StyleModern = 0 ,
StyleHistoric ,
NumOfStyles
} ;
enum Combinations {
CombSimple = 0 ,
CombCrossed ,
CombBackslashed ,
CombSlashed ,
NumOfCombinations
} ;
2012-05-26 14:26:10 +02:00
2012-08-10 20:50:27 +02:00
private :
2012-08-11 01:15:22 +02:00
static const QChar normParenthToChar [ NumOfParentheses ] ;
2012-05-26 14:26:10 +02:00
2012-08-01 19:06:20 +02:00
QString _displayText ; // the constructed display text (read-only)
2012-05-26 14:26:10 +02:00
int ord ; // the line ordinal of this element in the FB stack
// the parts making a FiguredBassItem up
2012-08-11 01:15:22 +02:00
Modifier _prefix ; // the accidental coming before the body
2012-08-10 20:50:27 +02:00
int _digit ; // the main digit (if present)
2012-08-11 01:15:22 +02:00
Modifier _suffix ; // the accidental coming after the body
2013-02-12 16:00:05 +01:00
ContLine _contLine ; // whether the item has continuation line or not
2012-08-11 01:15:22 +02:00
Parenthesis parenth [ 5 ] ; // each of the parenthesis: before, between and after parts
2012-05-26 14:26:10 +02:00
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 ) ;
2012-08-01 19:06:20 +02:00
void setDisplayText ( const QString & s ) { _displayText = s ; }
2012-08-10 20:50:27 +02:00
// read / write MusicXML support
2012-08-11 01:15:22 +02:00
QString Modifier2MusicXML ( FiguredBassItem : : Modifier prefix ) const ;
2012-08-01 19:06:20 +02:00
2012-05-26 14:26:10 +02:00
public :
2012-08-10 20:50:27 +02:00
FiguredBassItem ( Score * s = 0 , int line = 0 ) ;
2012-05-26 14:26:10 +02:00
FiguredBassItem ( const FiguredBassItem & ) ;
~ FiguredBassItem ( ) ;
FiguredBassItem & operator = ( const FiguredBassItem & ) ;
2013-01-17 11:33:11 +01:00
FiguredBassItem : : Modifier MusicXML2Modifier ( const QString prefix ) const ;
2012-05-26 14:26:10 +02:00
// standard re-implemented virtual functions
virtual FiguredBassItem * clone ( ) const { return new FiguredBassItem ( * this ) ; }
virtual ElementType type ( ) const { return INVALID ; }
virtual void draw ( QPainter * painter ) const ;
virtual void layout ( ) ;
2013-01-11 18:10:18 +01:00
virtual void read ( XmlReader & ) ;
2012-05-26 14:26:10 +02:00
virtual void write ( Xml & xml ) const ;
// read / write MusicXML
2013-01-17 11:33:11 +01:00
// void readMusicXML(XmlReader& de, bool paren, bool& extend);
2013-01-01 14:36:49 +01:00
void writeMusicXML ( Xml & xml , bool doFigure , bool doExtend ) const ;
2012-05-26 14:26:10 +02:00
bool startsWithParenthesis ( ) const ;
// specific API
const FiguredBass * figuredBass ( ) const { return ( FiguredBass * ) ( parent ( ) ) ; }
bool parse ( QString & text ) ;
2012-08-10 20:50:27 +02:00
// getters / setters
2012-08-11 01:15:22 +02:00
Modifier prefix ( ) const { return _prefix ; }
2013-01-17 11:33:11 +01:00
void setPrefix ( const Modifier & v ) { _prefix = v ; }
2012-08-11 01:15:22 +02:00
void undoSetPrefix ( Modifier pref ) ;
2012-08-10 20:50:27 +02:00
int digit ( ) const { return _digit ; }
2013-01-17 11:33:11 +01:00
void setDigit ( int val ) { _digit = val ; }
2012-08-10 20:50:27 +02:00
void undoSetDigit ( int digit ) ;
2012-08-11 01:15:22 +02:00
Modifier suffix ( ) const { return _suffix ; }
2013-01-17 11:33:11 +01:00
void setSuffix ( const Modifier & v ) { _suffix = v ; }
2012-08-11 01:15:22 +02:00
void undoSetSuffix ( Modifier suff ) ;
2013-02-12 16:00:05 +01:00
ContLine contLine ( ) const { return _contLine ; }
2012-08-11 01:15:22 +02:00
void undoSetContLine ( bool val ) ;
2012-08-14 14:58:43 +02:00
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 ] ; }
2013-01-17 11:33:11 +01:00
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 ; }
2012-08-14 14:58:43 +02:00
void undoSetParenth1 ( Parenthesis par ) ;
void undoSetParenth2 ( Parenthesis par ) ;
void undoSetParenth3 ( Parenthesis par ) ;
void undoSetParenth4 ( Parenthesis par ) ;
void undoSetParenth5 ( Parenthesis par ) ;
2012-08-10 20:50:27 +02:00
QString normalizedText ( ) const ;
QString displayText ( ) const { return _displayText ; }
2012-05-26 14:26:10 +02:00
2012-08-11 01:15:22 +02:00
virtual QVariant getProperty ( P_ID propertyId ) const ;
virtual bool setProperty ( P_ID propertyId , const QVariant & ) ;
virtual QVariant propertyDefault ( P_ID ) const ;
2012-05-26 14:26:10 +02:00
} ;
//---------------------------------------------------------
// FiguredBassFont
//---------------------------------------------------------
struct FiguredBassFont {
QString family ;
QString displayName ;
qreal defPitch ;
qreal defLineHeight ;
2013-02-10 07:01:31 +01:00
QChar displayAccidental [ FiguredBassItem : : NumOfModifiers ] ;
QChar displayParenthesis [ FiguredBassItem : : NumOfParentheses ] ;
QChar displayDigit [ FiguredBassItem : : NumOfStyles ] [ 10 ] [ FiguredBassItem : : NumOfCombinations ] ;
2012-05-26 14:26:10 +02:00
2013-01-11 18:10:18 +01:00
bool read ( XmlReader & ) ;
2012-05-26 14:26:10 +02:00
} ;
//---------------------------------------------------------
2012-07-25 11:49:34 +02:00
// @@ FiguredBass
2012-08-10 00:11:42 +02:00
/// A complete figured bass indication
//
// @P onNote bool whether it is placed on a note beginning or between notes (r/o)
// @P ticks int duration in ticks
2012-05-26 14:26:10 +02:00
//---------------------------------------------------------
class FiguredBass : public Text {
2012-05-28 11:29:21 +02:00
Q_OBJECT
2012-05-26 14:26:10 +02:00
2012-08-10 00:11:42 +02:00
// Q_PROPERTY(QDeclarativeListProperty<FiguredBassItem> items READ qmlItems)
Q_PROPERTY ( bool onNote READ onNote )
Q_PROPERTY ( int ticks READ ticks WRITE setTicks )
2012-05-26 14:26:10 +02:00
QList < 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)
2013-03-01 13:42:05 +01:00
qreal _printedLineLength ; // the length of lines actually printed (i.e. continuation lines)
2012-05-26 14:26:10 +02:00
void layoutLines ( ) ;
2012-08-10 20:50:27 +02:00
bool hasParentheses ( ) const ; // read / write MusicXML support
2012-08-01 19:06:20 +02:00
2012-05-26 14:26:10 +02:00
public :
2012-08-10 20:50:27 +02:00
FiguredBass ( Score * s = 0 ) ;
2012-05-26 14:26:10 +02:00
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 ElementType type ( ) const { return FIGURED_BASS ; }
virtual void draw ( QPainter * painter ) const ;
virtual void endEdit ( ) ;
virtual void layout ( ) ;
2013-01-11 18:10:18 +01:00
virtual void read ( XmlReader & ) ;
2012-05-26 14:26:10 +02:00
virtual void setSelected ( bool f ) ;
virtual void setVisible ( bool f ) ;
virtual void write ( Xml & xml ) const ;
// read / write MusicXML
2013-01-11 18:10:18 +01:00
bool readMusicXML ( XmlReader & de , int divisions , bool & extend ) ;
2013-01-01 14:36:49 +01:00
void writeMusicXML ( Xml & xml , bool doFigure , bool doExtend ) const ;
2012-05-26 14:26:10 +02:00
2012-08-10 20:50:27 +02:00
//DEBUG
2013-07-13 18:41:16 +02:00
Q_INVOKABLE Ms : : FiguredBassItem * addItem ( ) ;
2012-08-10 20:50:27 +02:00
2012-08-11 01:15:22 +02:00
// getters / setters / properties
2012-08-10 00:11:42 +02:00
// 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 )
2012-05-26 14:26:10 +02:00
return _lineLenghts . at ( idx ) ;
2012-08-10 00:11:42 +02:00
return 0 ; }
2013-03-01 13:42:05 +01:00
qreal printedLineLength ( ) const { return _printedLineLength ; }
2012-05-26 14:26:10 +02:00
bool onNote ( ) const { return _onNote ; }
2013-02-10 13:34:08 +01:00
int numOfItems ( ) const { return items . size ( ) ; }
2012-05-26 14:26:10 +02:00
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 ; }
2013-02-12 16:00:05 +01:00
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
2012-08-11 01:15:22 +02:00
virtual QVariant getProperty ( P_ID propertyId ) const ;
virtual bool setProperty ( P_ID propertyId , const QVariant & ) ;
virtual QVariant propertyDefault ( P_ID ) const ;
2013-01-17 11:33:11 +01:00
void appendItem ( const FiguredBassItem & item ) { items . append ( item ) ; }
2012-05-26 14:26:10 +02:00
} ;
2013-05-13 18:49:17 +02:00
} // namespace Ms
Q_DECLARE_METATYPE ( Ms : : FiguredBassItem : : Modifier ) ;
Q_DECLARE_METATYPE ( Ms : : FiguredBassItem : : Parenthesis ) ;
2012-05-26 14:26:10 +02:00
# endif