fix #7282 - support additional root/bass styles
German, Italian, lower case minor
This commit is contained in:
parent
8eb93dbdbe
commit
30d7afb2ed
15 changed files with 306 additions and 122 deletions
|
@ -104,7 +104,7 @@ QString HChord::name(int tpc) const
|
|||
static const HChord C0(0,3,6,9);
|
||||
static const HChord C1(0,3);
|
||||
|
||||
QString buf = tpc2name(tpc, false);
|
||||
QString buf = tpc2name(tpc, STANDARD, false);
|
||||
HChord c(*this);
|
||||
|
||||
int key = tpc2pitch(tpc);
|
||||
|
@ -1046,8 +1046,15 @@ bool ParsedChord::parse(const QString& s, const ChordList* cl, bool syntaxOnly)
|
|||
tok1L = "#";
|
||||
alter = true;
|
||||
}
|
||||
else
|
||||
else {
|
||||
_understandable = false;
|
||||
if (s.startsWith(tok1)) {
|
||||
// unrecognized token right from very beginning
|
||||
_xmlKind = "other";
|
||||
_xmlText = tok1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (alter) {
|
||||
if (tok2L == "4" && _xmlKind == "suspended-fourth")
|
||||
degree = "alt";
|
||||
|
@ -1282,7 +1289,7 @@ QString ParsedChord::fromXml(const QString& rawKind, const QString& rawKindText,
|
|||
_extension = QString("%1").arg(extension);
|
||||
|
||||
// validate kindText
|
||||
if (kindText != "") {
|
||||
if (kindText != "" && kind != "none") {
|
||||
ParsedChord validate;
|
||||
validate.parse(kindText,cl,false);
|
||||
// kindText should parse to produce same kind, no degrees
|
||||
|
|
|
@ -128,6 +128,9 @@ class ParsedChord {
|
|||
const QList<RenderAction>& renderList(const ChordList*);
|
||||
bool parseable() const { return _parseable; }
|
||||
bool understandable() const { return _understandable; }
|
||||
const QString& quality() const { return _quality; }
|
||||
const QString& extension() const { return _extension; }
|
||||
const QString& modifiers() const { return _modifiers; }
|
||||
const QString& xmlKind() const { return _xmlKind; }
|
||||
const QString& xmlText() const { return _xmlText; }
|
||||
const QString& xmlSymbols() const { return _xmlSymbols; }
|
||||
|
|
|
@ -29,9 +29,9 @@ namespace Ms {
|
|||
// harmonyName
|
||||
//---------------------------------------------------------
|
||||
|
||||
QString Harmony::harmonyName() const
|
||||
QString Harmony::harmonyName()
|
||||
{
|
||||
bool germanNames = score()->styleB(ST_useGermanNoteNames);
|
||||
determineRootBaseSpelling();
|
||||
|
||||
HChord hc = descr() ? descr()->chord : HChord();
|
||||
QString s, r, e, b;
|
||||
|
@ -39,7 +39,7 @@ QString Harmony::harmonyName() const
|
|||
if (_leftParen)
|
||||
s = "(";
|
||||
|
||||
r = tpc2name(_rootTpc, germanNames);
|
||||
r = tpc2name(_rootTpc, _rootSpelling, _rootLowerCase);
|
||||
|
||||
if (_textName != "")
|
||||
e = _textName;
|
||||
|
@ -65,7 +65,7 @@ QString Harmony::harmonyName() const
|
|||
}
|
||||
|
||||
if (_baseTpc != INVALID_TPC)
|
||||
b = "/" + tpc2name(_baseTpc, germanNames);
|
||||
b = "/" + tpc2name(_baseTpc, _baseSpelling, _baseLowerCase);
|
||||
|
||||
s += r + e + b;
|
||||
|
||||
|
@ -75,6 +75,26 @@ QString Harmony::harmonyName() const
|
|||
return s;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// rootName
|
||||
//---------------------------------------------------------
|
||||
|
||||
QString Harmony::rootName()
|
||||
{
|
||||
determineRootBaseSpelling();
|
||||
return tpc2name(_rootTpc, _rootSpelling, _rootLowerCase);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// baseName
|
||||
//---------------------------------------------------------
|
||||
|
||||
QString Harmony::baseName()
|
||||
{
|
||||
determineRootBaseSpelling();
|
||||
return tpc2name(_baseTpc, _baseSpelling, _baseLowerCase);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// resolveDegreeList
|
||||
// try to detect chord number and to eliminate degree
|
||||
|
@ -294,25 +314,93 @@ void Harmony::read(XmlReader& e)
|
|||
render();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// determineRootBaseSpelling
|
||||
//---------------------------------------------------------
|
||||
|
||||
void Harmony::determineRootBaseSpelling(NoteSpellingType& rootSpelling, bool& rootLowerCase, NoteSpellingType& baseSpelling, bool& baseLowerCase)
|
||||
{
|
||||
if (score()->styleB(ST_useStandardNoteNames))
|
||||
rootSpelling = STANDARD;
|
||||
else if (score()->styleB(ST_useGermanNoteNames))
|
||||
rootSpelling = GERMAN;
|
||||
else if (score()->styleB(ST_useItalianNoteNames))
|
||||
rootSpelling = ITALIAN;
|
||||
baseSpelling = rootSpelling;
|
||||
if (_parsedForm) {
|
||||
QString quality;
|
||||
quality = _parsedForm->quality();
|
||||
if (score()->styleB(ST_lowerCaseMinorChords) && (quality == "minor" || quality == "diminished" || quality == "half-diminished"))
|
||||
rootLowerCase = true;
|
||||
else
|
||||
baseLowerCase = false;
|
||||
}
|
||||
else
|
||||
rootLowerCase = false;
|
||||
if (baseSpelling == GERMAN)
|
||||
baseLowerCase = true;
|
||||
else
|
||||
baseLowerCase = false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// determineRootBaseSpelling
|
||||
//---------------------------------------------------------
|
||||
|
||||
void Harmony::determineRootBaseSpelling()
|
||||
{
|
||||
determineRootBaseSpelling(_rootSpelling, _rootLowerCase, _baseSpelling, _baseLowerCase);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// convertRoot
|
||||
// convert something like "C#" into tpc 21
|
||||
//---------------------------------------------------------
|
||||
|
||||
static int convertRoot(const QString& s, bool germanNames)
|
||||
static int convertRoot(const QString& s, NoteSpellingType spelling, int& idx)
|
||||
{
|
||||
int n = s.size();
|
||||
if (n < 1)
|
||||
static const int spellings[] = {
|
||||
// bb b - # ##
|
||||
0, 7, 14, 21, 28, // C
|
||||
2, 9, 16, 23, 30, // D
|
||||
4, 11, 18, 25, 32, // E
|
||||
-1, 6, 13, 20, 27, // F
|
||||
1, 8, 15, 22, 29, // G
|
||||
3, 10, 17, 24, 31, // A
|
||||
5, 12, 19, 26, 33, // B
|
||||
};
|
||||
if (s == "")
|
||||
return INVALID_TPC;
|
||||
int acci;
|
||||
switch (spelling) {
|
||||
case GERMAN: acci = 1; break;
|
||||
case ITALIAN: acci = 2; break;
|
||||
default: acci = 1; break;
|
||||
}
|
||||
idx = acci;
|
||||
int alter = 0;
|
||||
if (n > 1) {
|
||||
if (s[1].toLower().toLatin1() == 'b')
|
||||
int n = s.size();
|
||||
QString acc = s.right(n-acci);
|
||||
if (acc != "") {
|
||||
if (acc.startsWith("b")) {
|
||||
alter = -1;
|
||||
else if (s[1] == '#')
|
||||
idx += 1;
|
||||
}
|
||||
else if (spelling == GERMAN && acc.startsWith("es")) {
|
||||
alter = -1;
|
||||
idx += 2;
|
||||
}
|
||||
else if (acc.startsWith("#")) {
|
||||
alter = 1;
|
||||
idx += 1;
|
||||
}
|
||||
else if (spelling == GERMAN && acc.startsWith("is")) {
|
||||
alter = 1;
|
||||
idx += 2;
|
||||
}
|
||||
}
|
||||
int r;
|
||||
if (germanNames) {
|
||||
if (spelling == GERMAN) {
|
||||
switch(s[0].toLower().toLatin1()) {
|
||||
case 'c': r = 0; break;
|
||||
case 'd': r = 1; break;
|
||||
|
@ -330,17 +418,25 @@ static int convertRoot(const QString& s, bool germanNames)
|
|||
default:
|
||||
return INVALID_TPC;
|
||||
}
|
||||
static const int spellings[] = {
|
||||
// bb b - # ##
|
||||
0, 7, 14, 21, 28, // C
|
||||
2, 9, 16, 23, 30, // D
|
||||
4, 11, 18, 25, 32, // E
|
||||
-1, 6, 13, 20, 27, // F
|
||||
1, 8, 15, 22, 29, // G
|
||||
3, 10, 17, 24, 31, // A
|
||||
5, 12, 19, 26, 33, // B
|
||||
};
|
||||
r = spellings[r * 5 + alter + 2];
|
||||
}
|
||||
else if (spelling == ITALIAN) {
|
||||
QString ss = s.toLower().left(2);
|
||||
if (ss == "do")
|
||||
r = 0;
|
||||
else if (ss == "re")
|
||||
r = 1;
|
||||
else if (ss == "mi")
|
||||
r = 2;
|
||||
else if (ss == "fa")
|
||||
r = 3;
|
||||
else if (ss == "sol")
|
||||
r = 4;
|
||||
else if (ss == "la")
|
||||
r = 5;
|
||||
else if (ss == "si")
|
||||
r = 6;
|
||||
else
|
||||
return INVALID_TPC;
|
||||
}
|
||||
else {
|
||||
switch(s[0].toLower().toLatin1()) {
|
||||
|
@ -353,24 +449,14 @@ static int convertRoot(const QString& s, bool germanNames)
|
|||
case 'b': r = 6; break;
|
||||
default: return INVALID_TPC;
|
||||
}
|
||||
static const int spellings[] = {
|
||||
// bb b - # ##
|
||||
0, 7, 14, 21, 28, // C
|
||||
2, 9, 16, 23, 30, // D
|
||||
4, 11, 18, 25, 32, // E
|
||||
-1, 6, 13, 20, 27, // F
|
||||
1, 8, 15, 22, 29, // G
|
||||
3, 10, 17, 24, 31, // A
|
||||
5, 12, 19, 26, 33, // B
|
||||
};
|
||||
r = spellings[r * 5 + alter + 2];
|
||||
}
|
||||
r = spellings[r * 5 + alter + 2];
|
||||
return r;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// parseHarmony
|
||||
// determined root and bass tpc
|
||||
// determine root and bass tpc
|
||||
// compare body of chordname against chord list
|
||||
// return true if chord is recognized
|
||||
//---------------------------------------------------------
|
||||
|
@ -400,20 +486,22 @@ const ChordDescription* Harmony::parseHarmony(const QString& ss, int* root, int*
|
|||
int n = s.size();
|
||||
if (n < 1)
|
||||
return 0;
|
||||
bool germanNames = score()->styleB(ST_useGermanNoteNames);
|
||||
int r = convertRoot(s, germanNames);
|
||||
determineRootBaseSpelling();
|
||||
int idx;
|
||||
int r = convertRoot(s, _rootSpelling, idx);
|
||||
if (r == INVALID_TPC) {
|
||||
qDebug("1:parseHarmony failed <%s>", qPrintable(ss));
|
||||
return 0;
|
||||
}
|
||||
*root = r;
|
||||
int idx = ((n > 1) && ((s[1] == 'b') || (s[1] == '#'))) ? 2 : 1;
|
||||
// int idx = ((n > 1) && ((s[1] == 'b') || (s[1] == '#'))) ? 2 : 1;
|
||||
*base = INVALID_TPC;
|
||||
int slash = s.indexOf('/');
|
||||
if (slash != -1) {
|
||||
QString bs = s.mid(slash+1);
|
||||
s = s.mid(idx, slash - idx);
|
||||
*base = convertRoot(bs, germanNames);
|
||||
int dummy;
|
||||
*base = convertRoot(bs, _baseSpelling, dummy);
|
||||
}
|
||||
else
|
||||
s = s.mid(idx).simplified();
|
||||
|
@ -858,7 +946,7 @@ void Harmony::render(const QString& s, qreal& x, qreal& y)
|
|||
// render
|
||||
//---------------------------------------------------------
|
||||
|
||||
void Harmony::render(const QList<RenderAction>& renderList, qreal& x, qreal& y, int tpc)
|
||||
void Harmony::render(const QList<RenderAction>& renderList, qreal& x, qreal& y, int tpc, NoteSpellingType spelling, bool lowerCase)
|
||||
{
|
||||
ChordList* chordList = score()->style()->chordList();
|
||||
QStack<QPointF> stack;
|
||||
|
@ -895,39 +983,33 @@ void Harmony::render(const QList<RenderAction>& renderList, qreal& x, qreal& y,
|
|||
qDebug("RenderAction::RENDER_POP: stack empty");
|
||||
}
|
||||
else if (a.type == RenderAction::RENDER_NOTE) {
|
||||
bool germanNames = score()->styleB(ST_useGermanNoteNames);
|
||||
QChar c;
|
||||
QString c;
|
||||
int acc;
|
||||
tpc2name(tpc, germanNames, &c, &acc);
|
||||
tpc2name(tpc, spelling, lowerCase, c, acc);
|
||||
TextSegment* ts = new TextSegment(fontList[fontIdx], x, y);
|
||||
ChordSymbol cs = chordList->symbol(QString(c));
|
||||
ChordSymbol cs = chordList->symbol(c);
|
||||
if (cs.isValid()) {
|
||||
ts->font = fontList[cs.fontIdx];
|
||||
ts->setText(QString(cs.code));
|
||||
}
|
||||
else
|
||||
ts->setText(QString(c));
|
||||
ts->setText(c);
|
||||
textList.append(ts);
|
||||
x += ts->width();
|
||||
}
|
||||
else if (a.type == RenderAction::RENDER_ACCIDENTAL) {
|
||||
QChar c;
|
||||
int acc;
|
||||
tpc2name(tpc, false, &c, &acc);
|
||||
if (acc) {
|
||||
QString c;
|
||||
QString acc;
|
||||
tpc2name(tpc, spelling, lowerCase, c, acc);
|
||||
if (acc != "") {
|
||||
TextSegment* ts = new TextSegment(fontList[fontIdx], x, y);
|
||||
QString s;
|
||||
if (acc == -1)
|
||||
s = "b";
|
||||
else if (acc == 1)
|
||||
s = "#";
|
||||
ChordSymbol cs = chordList->symbol(s);
|
||||
ChordSymbol cs = chordList->symbol(acc);
|
||||
if (cs.isValid()) {
|
||||
ts->font = fontList[cs.fontIdx];
|
||||
ts->setText(QString(cs.code));
|
||||
}
|
||||
else
|
||||
ts->setText(s);
|
||||
ts->setText(acc);
|
||||
textList.append(ts);
|
||||
x += ts->width();
|
||||
}
|
||||
|
@ -969,11 +1051,13 @@ void Harmony::render(const TextStyle* st)
|
|||
textList.clear();
|
||||
qreal x = 0.0, y = 0.0;
|
||||
|
||||
determineRootBaseSpelling();
|
||||
|
||||
if (_leftParen)
|
||||
render("( ", x, y);
|
||||
|
||||
// render root
|
||||
render(chordList->renderListRoot, x, y, _rootTpc);
|
||||
render(chordList->renderListRoot, x, y, _rootTpc, _rootSpelling, _rootLowerCase);
|
||||
|
||||
// render extension
|
||||
const ChordDescription* cd = getDescription();
|
||||
|
@ -982,7 +1066,7 @@ void Harmony::render(const TextStyle* st)
|
|||
|
||||
// render bass
|
||||
if (_baseTpc != INVALID_TPC)
|
||||
render(chordList->renderListBase, x, y, _baseTpc);
|
||||
render(chordList->renderListBase, x, y, _baseTpc, _baseSpelling, _baseLowerCase);
|
||||
|
||||
if (_rightParen)
|
||||
render(" )", x, y);
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#define __HARMONY_H__
|
||||
|
||||
#include "text.h"
|
||||
#include "pitchspelling.h"
|
||||
|
||||
namespace Ms {
|
||||
|
||||
|
@ -87,9 +88,13 @@ class Harmony : public Text {
|
|||
|
||||
mutable QRectF _tbbox;
|
||||
|
||||
NoteSpellingType _rootSpelling, _baseSpelling;
|
||||
bool _rootLowerCase, _baseLowerCase;
|
||||
|
||||
void determineRootBaseSpelling();
|
||||
virtual void draw(QPainter*) const;
|
||||
void render(const QString&, qreal&, qreal&);
|
||||
void render(const QList<RenderAction>& renderList, qreal&, qreal&, int tpc);
|
||||
void render(const QList<RenderAction>& renderList, qreal&, qreal&, int tpc, NoteSpellingType spelling = STANDARD, bool lowerCase = false);
|
||||
|
||||
public:
|
||||
Harmony(Score* = 0);
|
||||
|
@ -110,6 +115,8 @@ class Harmony : public Text {
|
|||
const ChordDescription* getDescription(const QString&, const ParsedChord* pc = 0);
|
||||
const ChordDescription* generateDescription();
|
||||
|
||||
void determineRootBaseSpelling(NoteSpellingType& rootSpelling, bool& rootLowerCase, NoteSpellingType& baseSpelling, bool& baseLowerCase);
|
||||
|
||||
virtual void layout();
|
||||
|
||||
const QRectF& bboxtight() const { return _tbbox; }
|
||||
|
@ -128,6 +135,8 @@ class Harmony : public Text {
|
|||
int rootTpc() const { return _rootTpc; }
|
||||
void setRootTpc(int val) { _rootTpc = val; }
|
||||
void setTextName(const QString& s) { _textName = s; }
|
||||
QString rootName();
|
||||
QString baseName();
|
||||
void addDegree(const HDegree& d);
|
||||
int numberOfDegrees() const;
|
||||
HDegree degree(int i) const;
|
||||
|
@ -136,7 +145,7 @@ class Harmony : public Text {
|
|||
|
||||
virtual void write(Xml& xml) const;
|
||||
virtual void read(XmlReader&);
|
||||
QString harmonyName() const;
|
||||
QString harmonyName();
|
||||
void render(const TextStyle* ts = 0);
|
||||
|
||||
const ChordDescription* parseHarmony(const QString& s, int* root, int* base, bool syntaxOnly = false);
|
||||
|
|
|
@ -219,41 +219,64 @@ int tpc2alterByKey(int tpc, int key) {
|
|||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// printTpc
|
||||
// print note name
|
||||
// tpc2name
|
||||
// return note name
|
||||
//---------------------------------------------------------
|
||||
|
||||
QString tpc2name(int tpc, bool germanNames)
|
||||
QString tpc2name(int tpc, NoteSpellingType spelling, bool lowerCase)
|
||||
{
|
||||
const char names[] = "FCGDAEB";
|
||||
int acc = ((tpc+1) / 7) - 2;
|
||||
QString s(names[(tpc + 1) % 7]);
|
||||
if (germanNames && (s == "B")) {
|
||||
if (acc == -1)
|
||||
return s;
|
||||
s = "H";
|
||||
}
|
||||
switch(acc) {
|
||||
case -2: s += "bb"; break;
|
||||
case -1: s += "b"; break;
|
||||
case 0: break;
|
||||
case 1: s += "#"; break;
|
||||
case 2: s += "##"; break;
|
||||
default:
|
||||
qDebug("tpc2name(%d): acc %d\n", tpc, acc);
|
||||
s += "??";
|
||||
break;
|
||||
}
|
||||
return s;
|
||||
QString s;
|
||||
QString acc;
|
||||
tpc2name(tpc, spelling, lowerCase, s, acc);
|
||||
return s + acc;
|
||||
}
|
||||
|
||||
void tpc2name(int tpc, bool germanNames, QChar* name, int* acc)
|
||||
//---------------------------------------------------------
|
||||
// tpc2name
|
||||
//---------------------------------------------------------
|
||||
|
||||
void tpc2name(int tpc, NoteSpellingType spelling, bool lowerCase, QString& s, QString& acc)
|
||||
{
|
||||
int n;
|
||||
tpc2name(tpc, spelling, lowerCase, s, n);
|
||||
switch (n) {
|
||||
case -2: acc = "bb" ; break;
|
||||
case -1: acc = (spelling != GERMAN) ? "b" : "es"; break;
|
||||
case 0: acc = ""; break;
|
||||
case 1: acc = (spelling != GERMAN) ? "#" : "is"; break;
|
||||
case 2: acc = "##"; break;
|
||||
default:
|
||||
qDebug("tpc2name(%d): acc %d\n", tpc, n);
|
||||
acc = "";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// tpc2name
|
||||
//---------------------------------------------------------
|
||||
|
||||
void tpc2name(int tpc, NoteSpellingType spelling, bool lowerCase, QString& s, int& acc)
|
||||
{
|
||||
const char names[] = "FCGDAEB";
|
||||
const char gnames[] = "FCGDAEH";
|
||||
*acc = ((tpc+1) / 7) - 2;
|
||||
const QString inames[] = { "Fa", "Do", "Sol", "Re", "La", "Mi", "Si" };
|
||||
|
||||
acc = ((tpc+1) / 7) - 2;
|
||||
int idx = (tpc + 1) % 7;
|
||||
*name = QChar::fromLatin1(germanNames ? gnames[idx] : names[idx]);
|
||||
switch (spelling) {
|
||||
case GERMAN:
|
||||
s = gnames[idx];
|
||||
if (s == "H" && acc == -1) {
|
||||
s = "B";
|
||||
acc = 0;
|
||||
}
|
||||
break;
|
||||
case ITALIAN: s = inames[idx]; break;
|
||||
default: s = names[idx]; break;
|
||||
}
|
||||
if (lowerCase)
|
||||
s = s.toLower();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
|
|
@ -49,6 +49,7 @@ const int STEP_DELTA_TPC = 4; // the number of steps in a tpc step (
|
|||
// pitch2tpc(pitch) replaced by pitch2tpc(pitch, KEY_C, PREFER_NEAREST)
|
||||
|
||||
enum { PREFER_FLATS=8, PREFER_NEAREST=11, PREFER_SHARPS=13 };
|
||||
enum NoteSpellingType { STANDARD = 0, GERMAN, ITALIAN };
|
||||
|
||||
extern int pitch2tpc(int pitch, int key, int prefer);
|
||||
|
||||
|
@ -56,8 +57,9 @@ extern void spell(QList<Event>& notes, int);
|
|||
extern void spell(QList<Note*>& notes);
|
||||
extern int computeWindow(const QList<Note*>& notes, int start, int end);
|
||||
extern int tpc(int idx, int pitch, int opt);
|
||||
extern QString tpc2name(int tpc, bool germanNames);
|
||||
extern void tpc2name(int tpc, bool germanNames, QChar* name, int* acc);
|
||||
extern QString tpc2name(int tpc, NoteSpellingType spelling, bool lowerCase);
|
||||
extern void tpc2name(int tpc, NoteSpellingType spelling, bool lowerCase, QString& s, QString& acc);
|
||||
extern void tpc2name(int tpc, NoteSpellingType spelling, bool lowerCase, QString& s, int& acc);
|
||||
extern int step2tpc(const QString& stepName, AccidentalVal alter);
|
||||
extern int step2tpc(int step);
|
||||
extern int step2tpc(int step, AccidentalVal alter);
|
||||
|
|
|
@ -123,7 +123,9 @@ static const StyleVal style114[] = {
|
|||
StyleVal(ST_genCourtesyTimesig, true),
|
||||
StyleVal(ST_genCourtesyKeysig, true),
|
||||
|
||||
StyleVal(ST_useStandardNoteNames, true),
|
||||
StyleVal(ST_useGermanNoteNames, false),
|
||||
StyleVal(ST_useSolfeggioNoteNames, false),
|
||||
StyleVal(ST_chordDescriptionFile, QString("stdchords.xml")),
|
||||
StyleVal(ST_chordStyle, QString("custom")),
|
||||
StyleVal(ST_chordsXmlFile, true),
|
||||
|
@ -621,8 +623,8 @@ Score::FileError Score::read114(XmlReader& e)
|
|||
style()->set(ST_voltaY, Spatium(-2.0));
|
||||
if (styleB(ST_hideEmptyStaves) == true) // http://musescore.org/en/node/16228
|
||||
style()->set(ST_dontHideStavesInFirstSystem, false);
|
||||
if (styleSt(ST_chordDescriptionFile) == "chords_std.xml")
|
||||
style()->set(ST_chordDescriptionFile, QString("stdchords.xml"));
|
||||
if (styleB(ST_useGermanNoteNames))
|
||||
style()->set(ST_useStandardNoteNames, false);
|
||||
|
||||
_showOmr = false;
|
||||
|
||||
|
|
|
@ -138,7 +138,10 @@ StyleType styleTypes[] = {
|
|||
StyleType("genCourtesyTimesig", ST_BOOL),
|
||||
StyleType("genCourtesyKeysig", ST_BOOL),
|
||||
StyleType("genCourtesyClef", ST_BOOL),
|
||||
StyleType("useStandardNoteNames", ST_BOOL),
|
||||
StyleType("useGermanNoteNames", ST_BOOL),
|
||||
StyleType("useItalianNoteNames", ST_BOOL),
|
||||
StyleType("lowerCaseMinorChords", ST_BOOL),
|
||||
StyleType("chordStyle", ST_STRING),
|
||||
StyleType("chordsXmlFile", ST_BOOL),
|
||||
StyleType("chordDescriptionFile", ST_STRING),
|
||||
|
@ -532,7 +535,10 @@ StyleData::StyleData()
|
|||
StyleVal(ST_genCourtesyKeysig, true),
|
||||
StyleVal(ST_genCourtesyClef, true),
|
||||
|
||||
StyleVal(ST_useStandardNoteNames, true),
|
||||
StyleVal(ST_useGermanNoteNames, false),
|
||||
StyleVal(ST_useItalianNoteNames, false),
|
||||
StyleVal(ST_lowerCaseMinorChords, false),
|
||||
StyleVal(ST_chordStyle, QString("std")),
|
||||
StyleVal(ST_chordsXmlFile, false),
|
||||
StyleVal(ST_chordDescriptionFile, QString("chords_std.xml")),
|
||||
|
|
|
@ -256,7 +256,10 @@ enum StyleIdx {
|
|||
ST_genCourtesyKeysig,
|
||||
ST_genCourtesyClef,
|
||||
|
||||
ST_useStandardNoteNames,
|
||||
ST_useGermanNoteNames,
|
||||
ST_useItalianNoteNames,
|
||||
ST_lowerCaseMinorChords,
|
||||
ST_chordStyle,
|
||||
ST_chordsXmlFile,
|
||||
ST_chordDescriptionFile,
|
||||
|
@ -268,7 +271,6 @@ enum StyleIdx {
|
|||
ST_dontHideStavesInFirstSystem,
|
||||
ST_stemDir1,
|
||||
ST_stemDir2,
|
||||
|
||||
ST_stemDir3,
|
||||
ST_stemDir4,
|
||||
ST_gateTime,
|
||||
|
|
|
@ -1364,7 +1364,6 @@ HarmonyView::HarmonyView()
|
|||
void HarmonyView::setElement(Element* e)
|
||||
{
|
||||
Harmony* harmony = (Harmony*)e;
|
||||
bool germanNames = e->score()->styleB(ST_useGermanNoteNames);
|
||||
|
||||
tb.textStyle->clear();
|
||||
for (int i = 0; i < TEXT_STYLES; ++i)
|
||||
|
@ -1391,12 +1390,12 @@ void HarmonyView::setElement(Element* e)
|
|||
if (harmony->rootTpc() == INVALID_TPC)
|
||||
hb.rootName->setText("");
|
||||
else
|
||||
hb.rootName->setText(tpc2name(harmony->rootTpc(),germanNames));
|
||||
hb.rootName->setText(harmony->rootName());
|
||||
hb.bassTpc->setValue(harmony->baseTpc());
|
||||
if (harmony->baseTpc() == INVALID_TPC)
|
||||
hb.bassName->setText("");
|
||||
else
|
||||
hb.bassName->setText(tpc2name(harmony->baseTpc(),germanNames));
|
||||
hb.bassName->setText(harmony->baseName());
|
||||
hb.chordId->setValue(harmony->id());
|
||||
hb.chordName->setText(harmony->hTextName());
|
||||
hb.userName->setText(harmony->hUserName());
|
||||
|
|
|
@ -261,7 +261,11 @@ void EditStyle::getValues()
|
|||
lstyle.setChordList(cl, customChords);
|
||||
lstyle.set(ST_chordDescriptionFile, chordDescriptionFile->text());
|
||||
}
|
||||
|
||||
lstyle.set(ST_useStandardNoteNames, useStandardNoteNames->isChecked());
|
||||
lstyle.set(ST_useGermanNoteNames, useGermanNoteNames->isChecked());
|
||||
lstyle.set(ST_useItalianNoteNames, useItalianNoteNames->isChecked());
|
||||
lstyle.set(ST_lowerCaseMinorChords, lowerCaseMinorChords->isChecked());
|
||||
|
||||
lstyle.set(ST_concertPitch, concertPitch->isChecked());
|
||||
lstyle.set(ST_createMultiMeasureRests, multiMeasureRests->isChecked());
|
||||
|
@ -495,7 +499,10 @@ void EditStyle::setValues()
|
|||
chordsCustom->setChecked(true);
|
||||
chordDescriptionGroup->setEnabled(true);
|
||||
}
|
||||
useStandardNoteNames->setChecked(lstyle.valueB(ST_useStandardNoteNames));
|
||||
useGermanNoteNames->setChecked(lstyle.valueB(ST_useGermanNoteNames));
|
||||
useItalianNoteNames->setChecked(lstyle.valueB(ST_useItalianNoteNames));
|
||||
lowerCaseMinorChords->setChecked(lstyle.valueB(ST_lowerCaseMinorChords));
|
||||
concertPitch->setChecked(lstyle.valueB(ST_concertPitch));
|
||||
|
||||
multiMeasureRests->setChecked(lstyle.valueB(ST_createMultiMeasureRests));
|
||||
|
|
|
@ -3696,26 +3696,60 @@ p, li { white-space: pre-wrap; }
|
|||
<property name="title">
|
||||
<string>Root / bass spelling</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_37">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="useGermanNoteNames">
|
||||
<property name="text">
|
||||
<string>Use German names</string>
|
||||
</property>
|
||||
</widget>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="useStandardNoteNames">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>A, Bb, B, C, ...</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Standard</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="useGermanNoteNames">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>A, B, H, C, ...</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>German</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="useItalianNoteNames">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>La, Sib, Si, Do, ...</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Italian</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_12">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_12">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<widget class="QCheckBox" name="lowerCaseMinorChords">
|
||||
<property name="text">
|
||||
<string>Lower case minor chords</string>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
@ -4529,7 +4563,10 @@ p, li { white-space: pre-wrap; }
|
|||
<tabstop>chordDescriptionFile</tabstop>
|
||||
<tabstop>chordDescriptionFileButton</tabstop>
|
||||
<tabstop>chordsXmlFile</tabstop>
|
||||
<tabstop>useStandardNoteNames</tabstop>
|
||||
<tabstop>useGermanNoteNames</tabstop>
|
||||
<tabstop>useItalianNoteNames</tabstop>
|
||||
<tabstop>lowerCaseMinorChords</tabstop>
|
||||
<tabstop>harmonyY</tabstop>
|
||||
<tabstop>harmonyFretDist</tabstop>
|
||||
<tabstop>minHarmonyDistance</tabstop>
|
||||
|
|
|
@ -4582,7 +4582,7 @@ void ExportMusicXml::harmony(Harmony const* const h, FretDiagram const* const fd
|
|||
//
|
||||
xml.stag("direction");
|
||||
xml.stag("direction-type");
|
||||
xml.tag("words default-y=\"100\"", h->text());
|
||||
xml.tag("words", h->text());
|
||||
xml.etag();
|
||||
xml.etag();
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ class HarmonyCanvas : public QFrame {
|
|||
virtual void dragLeaveEvent(QDragLeaveEvent*);
|
||||
virtual void dragMoveEvent(QDragMoveEvent*);
|
||||
|
||||
void render(const QList<RenderAction>&, double& x, double& y, int tpc);
|
||||
void render(const QList<RenderAction>&, double& x, double& y, int tpc, NoteSpellingType spelling, bool lowerCase);
|
||||
|
||||
private slots:
|
||||
void deleteAction();
|
||||
|
|
|
@ -301,7 +301,7 @@ void HarmonyCanvas::paintEvent(QPaintEvent* event)
|
|||
// render
|
||||
//---------------------------------------------------------
|
||||
|
||||
void HarmonyCanvas::render(const QList<RenderAction>& renderList, double& x, double& y, int tpc)
|
||||
void HarmonyCanvas::render(const QList<RenderAction>& renderList, double& x, double& y, int tpc, NoteSpellingType spelling, bool lowerCase)
|
||||
{
|
||||
QStack<QPointF> stack;
|
||||
int fontIdx = 0;
|
||||
|
@ -352,10 +352,9 @@ void HarmonyCanvas::render(const QList<RenderAction>& renderList, double& x, dou
|
|||
qDebug("RenderAction::RENDER_POP: stack empty\n");
|
||||
}
|
||||
else if (a.type == RenderAction::RENDER_NOTE) {
|
||||
bool germanNames = gscore->styleB(ST_useGermanNoteNames);
|
||||
QChar c;
|
||||
QString c;
|
||||
int acc;
|
||||
tpc2name(tpc, germanNames, &c, &acc);
|
||||
tpc2name(tpc, spelling, lowerCase, c, acc);
|
||||
TextSegment* ts = new TextSegment(fontList[fontIdx], x, y);
|
||||
ChordSymbol cs = chordList->symbol(QString(c));
|
||||
if (cs.isValid()) {
|
||||
|
@ -368,9 +367,9 @@ void HarmonyCanvas::render(const QList<RenderAction>& renderList, double& x, dou
|
|||
x += ts->width();
|
||||
}
|
||||
else if (a.type == RenderAction::RENDER_ACCIDENTAL) {
|
||||
QChar c;
|
||||
QString c;
|
||||
int acc;
|
||||
tpc2name(tpc, false, &c, &acc);
|
||||
tpc2name(tpc, spelling, lowerCase, c, acc);
|
||||
if (acc) {
|
||||
TextSegment* ts = new TextSegment(fontList[fontIdx], x, y);
|
||||
QString s;
|
||||
|
@ -449,8 +448,12 @@ void HarmonyCanvas::setChordDescription(ChordDescription* sd, ChordList* sl)
|
|||
if (chordList) {
|
||||
int tpc = 14;
|
||||
double x = 0.0, y = 0.0;
|
||||
render(chordList->renderListRoot, x, y, 14);
|
||||
render(chordDescription->renderList, x, y, tpc);
|
||||
NoteSpellingType rootSpelling, baseSpelling;
|
||||
bool rootLowerCase, baseLowerCase;
|
||||
Harmony h;
|
||||
h.determineRootBaseSpelling(rootSpelling, rootLowerCase, baseSpelling, baseLowerCase);
|
||||
render(chordList->renderListRoot, x, y, tpc, rootSpelling, rootLowerCase);
|
||||
render(chordDescription->renderList, x, y, tpc, baseSpelling, baseLowerCase);
|
||||
}
|
||||
moveElement = 0;
|
||||
dragElement = 0;
|
||||
|
|
Loading…
Reference in a new issue