Score accessibility system.
Provides screen-reader feedback for the selected element.
This commit is contained in:
parent
6377816fa7
commit
6460485d3f
73 changed files with 1242 additions and 164 deletions
|
@ -474,5 +474,15 @@ bool Accidental::setProperty(P_ID propertyId, const QVariant& v)
|
|||
score()->setLayoutAll(true); // spacing changes
|
||||
return true;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// accessibleInfo
|
||||
//---------------------------------------------------------
|
||||
|
||||
QString Accidental::accessibleInfo()
|
||||
{
|
||||
return Element::accessibleInfo() + " " + QString(Accidental::subtype2name(accidentalType()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -144,7 +144,10 @@ class Accidental : public Element {
|
|||
static const char* subtype2name(Type);
|
||||
static Type value2subtype(AccidentalVal);
|
||||
static Type name2subtype(const QString&);
|
||||
|
||||
QString accessibleInfo() override;
|
||||
};
|
||||
|
||||
} // namespace Ms
|
||||
|
||||
Q_DECLARE_METATYPE(Ms::Accidental::Role);
|
||||
|
|
|
@ -718,5 +718,26 @@ Element* Ambitus::prevElement()
|
|||
{
|
||||
return segment()->lastInPrevSegments(staffIdx());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// accessibleInfo
|
||||
//---------------------------------------------------------
|
||||
QString Ambitus::accessibleInfo()
|
||||
{
|
||||
return Element::accessibleInfo() + " " +
|
||||
tr("Top pitch: %1%2").arg(tpc2name(topTpc(), NoteSpellingType::STANDARD, false, false)).arg(QString::number(topOctave())) + " " +
|
||||
tr("Bottom pitch: %1%2").arg(tpc2name(bottomTpc(), NoteSpellingType::STANDARD, false, false)).arg(QString::number(bottomOctave()));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// screenReaderInfo
|
||||
//---------------------------------------------------------
|
||||
|
||||
QString Ambitus::screenReaderInfo()
|
||||
{
|
||||
return Element::screenReaderInfo() + " " +
|
||||
tr("Top pitch: %1%2").arg(tpc2name(topTpc(), NoteSpellingType::STANDARD, false, true)).arg(QString::number(topOctave())) + " " +
|
||||
tr("Bottom pitch: %1%2").arg(tpc2name(bottomTpc(), NoteSpellingType::STANDARD, false, true)).arg(QString::number(bottomOctave()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -88,6 +88,8 @@ class Ambitus : public Element {
|
|||
virtual void setTrack(int val);
|
||||
virtual Space space() const;
|
||||
virtual void write(Xml&) const;
|
||||
virtual QString accessibleInfo() override;
|
||||
virtual QString screenReaderInfo() override;
|
||||
|
||||
// properties
|
||||
QVariant getProperty(P_ID ) const;
|
||||
|
|
|
@ -626,6 +626,16 @@ qreal Articulation::mag() const
|
|||
{
|
||||
return parent() ? parent()->mag() * score()->styleD(StyleIdx::articulationMag): 1.0;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// accessibleInfo
|
||||
//---------------------------------------------------------
|
||||
|
||||
QString Articulation::accessibleInfo()
|
||||
{
|
||||
return Element::accessibleInfo() + " " + subtypeUserName();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -134,8 +134,9 @@ class Articulation : public Element {
|
|||
_articulationType == ArticulationType::Shortfermata ||
|
||||
_articulationType == ArticulationType::Longfermata ||
|
||||
_articulationType == ArticulationType::Verylongfermata; }
|
||||
};
|
||||
|
||||
QString accessibleInfo() override;
|
||||
};
|
||||
|
||||
} // namespace Ms
|
||||
#endif
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "articulation.h"
|
||||
#include "stafftype.h"
|
||||
#include "xml.h"
|
||||
#include "marker.h"
|
||||
|
||||
namespace Ms {
|
||||
|
||||
|
@ -50,6 +51,22 @@ static const char* barLineNames[] = {
|
|||
QT_TRANSLATE_NOOP("barline", "dotted")
|
||||
};
|
||||
|
||||
const barLineTableItem barLineTable[] = {
|
||||
{ BarLineType::NORMAL, QT_TRANSLATE_NOOP("Palette", "Normal") },
|
||||
{ BarLineType::BROKEN, QT_TRANSLATE_NOOP("Palette", "Dashed style") },
|
||||
{ BarLineType::DOTTED, QT_TRANSLATE_NOOP("Palette", "Dotted style") },
|
||||
{ BarLineType::END, QT_TRANSLATE_NOOP("Palette", "End Bar style") },
|
||||
{ BarLineType::DOUBLE, QT_TRANSLATE_NOOP("Palette", "Double Bar style") },
|
||||
{ BarLineType::START_REPEAT, QT_TRANSLATE_NOOP("Palette", "Start Repeat") },
|
||||
{ BarLineType::END_REPEAT, QT_TRANSLATE_NOOP("Palette", "End Repeat") },
|
||||
{ BarLineType::END_START_REPEAT, QT_TRANSLATE_NOOP("Palette", "End-Start Repeat") },
|
||||
};
|
||||
|
||||
unsigned int barLineTableSize()
|
||||
{
|
||||
return sizeof(barLineTable)/sizeof(*barLineTable);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// userTypeName
|
||||
//---------------------------------------------------------
|
||||
|
@ -59,6 +76,16 @@ QString BarLine::userTypeName(BarLineType t)
|
|||
return qApp->translate("barline", barLineNames[int(t)]);
|
||||
}
|
||||
|
||||
QString BarLine::userTypeName2(BarLineType t)
|
||||
{
|
||||
for (unsigned i = 0; i < sizeof(barLineTable)/sizeof(*barLineTable); ++i) {
|
||||
if(barLineTable[i].type == t)
|
||||
return barLineTable[i].name;
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------
|
||||
// BarLine
|
||||
//---------------------------------------------------------
|
||||
|
@ -1155,5 +1182,76 @@ Element* BarLine::prevElement()
|
|||
return parent()->prevElement();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// accessibleInfo
|
||||
//---------------------------------------------------------
|
||||
|
||||
QString BarLine::accessibleInfo()
|
||||
{
|
||||
return Element::accessibleInfo() + " " + BarLine::userTypeName2(this->barLineType());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// accessibleExtraInfo
|
||||
//---------------------------------------------------------
|
||||
|
||||
QString BarLine::accessibleExtraInfo()
|
||||
{
|
||||
if (parent()->type() == Element::Type::SEGMENT) {
|
||||
Segment* seg = static_cast<Segment*>(parent());
|
||||
QString rez = "";
|
||||
|
||||
foreach(Element* e, *el())
|
||||
rez += " " + e->screenReaderInfo();
|
||||
|
||||
foreach (Element* e, seg->annotations()) {
|
||||
if (e->track() == track())
|
||||
rez += " " + e->screenReaderInfo();
|
||||
}
|
||||
Measure* m = seg->measure();
|
||||
|
||||
if (m) {
|
||||
//jumps
|
||||
foreach (Element* e, *m->el()) {
|
||||
if(e->type() == Element::Type::JUMP)
|
||||
rez+= " " + e->screenReaderInfo();
|
||||
if(e->type() == Element::Type::MARKER) {
|
||||
Marker* m = static_cast<Marker*>(e);
|
||||
if (m->markerType() == Marker::Type::FINE)
|
||||
rez += " " + e->screenReaderInfo();
|
||||
}
|
||||
|
||||
}
|
||||
//markers
|
||||
Measure* nextM = m->nextMeasureMM();
|
||||
if (nextM) {
|
||||
foreach (Element* e, *nextM->el()) {
|
||||
if(e->type() == Element::Type::MARKER)
|
||||
if(static_cast<Marker*>(e)->markerType() == Marker::Type::FINE)
|
||||
continue; //added above^
|
||||
rez += " " + e->screenReaderInfo();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int tick = seg->tick();
|
||||
SpannerMap smap = score()->spannerMap();
|
||||
std::vector< ::Interval<Spanner*> > spanners = smap.findOverlapping(tick, tick);
|
||||
for (std::vector< ::Interval<Spanner*> >::iterator i = spanners.begin(); i < spanners.end(); i++) {
|
||||
::Interval<Spanner*> interval = *i;
|
||||
Spanner* s = interval.value;
|
||||
if (s->type() == Element::Type::VOLTA) {
|
||||
if(s->tick() == tick)
|
||||
rez += " " + tr("Start of %1").arg(s->screenReaderInfo());
|
||||
if(s->tick2() == tick)
|
||||
rez += " " + tr("End of %1").arg(s->screenReaderInfo());
|
||||
}
|
||||
}
|
||||
return rez;
|
||||
}
|
||||
|
||||
return Element::accessibleExtraInfo();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -113,9 +113,11 @@ class BarLine : public Element {
|
|||
const ElementList* el() const { return &_el; }
|
||||
|
||||
static QString userTypeName(BarLineType);
|
||||
static QString userTypeName2(BarLineType);
|
||||
|
||||
QString barLineTypeName() const;
|
||||
void setBarLineType(const QString& s);
|
||||
void setBarLineType(BarLineType i) { _barLineType = i; }
|
||||
void setBarLineType(BarLineType i) { _barLineType = i; }
|
||||
BarLineType barLineType() const { return _barLineType; }
|
||||
|
||||
virtual QVariant getProperty(P_ID propertyId) const override;
|
||||
|
@ -130,8 +132,16 @@ class BarLine : public Element {
|
|||
|
||||
virtual Element* nextElement() override;
|
||||
virtual Element* prevElement() override;
|
||||
QString accessibleInfo() override;
|
||||
QString accessibleExtraInfo() override;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
BarLineType type;
|
||||
const char* name;
|
||||
} barLineTableItem;
|
||||
extern const barLineTableItem barLineTable[];
|
||||
unsigned int barLineTableSize();
|
||||
|
||||
} // namespace Ms
|
||||
#endif
|
||||
|
|
|
@ -126,5 +126,20 @@ Element* Breath::prevElement()
|
|||
{
|
||||
return segment()->lastInPrevSegments(staffIdx());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// accessibleInfo
|
||||
//---------------------------------------------------------
|
||||
|
||||
QString Breath::accessibleInfo()
|
||||
{
|
||||
switch (breathType()) {
|
||||
case 2:
|
||||
case 3:
|
||||
return tr("Caesura");
|
||||
default:
|
||||
return tr("Breath");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@ class Breath : public Element {
|
|||
|
||||
virtual Element* nextElement() override;
|
||||
virtual Element* prevElement() override;
|
||||
virtual QString accessibleInfo() override;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -2816,6 +2816,7 @@ TremoloChordType Chord::tremoloChordType() const
|
|||
return TremoloChordType::TremoloSingle;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------
|
||||
// nextElement
|
||||
//---------------------------------------------------------
|
||||
|
@ -2854,5 +2855,31 @@ Element* Chord::prevElement()
|
|||
return ChordRest::prevElement();
|
||||
}
|
||||
|
||||
QString Chord::accessibleExtraInfo()
|
||||
{
|
||||
QString rez = "";
|
||||
|
||||
if (!isGrace()) {
|
||||
foreach (Chord* c, graceNotes()) {
|
||||
foreach (Note* n, c->notes()) {
|
||||
rez = " " + n->screenReaderInfo();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (arpeggio())
|
||||
rez = rez + " " + arpeggio()->screenReaderInfo();
|
||||
|
||||
if (tremolo())
|
||||
rez = rez + " " + tremolo()->screenReaderInfo();
|
||||
|
||||
if (glissando())
|
||||
rez = rez + " " + glissando()->screenReaderInfo();
|
||||
|
||||
foreach (Element* e, el())
|
||||
rez = rez + " " + e->screenReaderInfo();
|
||||
|
||||
return rez + " " + ChordRest::accessibleExtraInfo();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -213,8 +213,10 @@ class Chord : public ChordRest {
|
|||
|
||||
void sortNotes();
|
||||
|
||||
|
||||
virtual Element* nextElement() override;
|
||||
virtual Element* prevElement() override;
|
||||
virtual QString accessibleExtraInfo() override;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -19,6 +19,14 @@
|
|||
|
||||
namespace Ms {
|
||||
|
||||
const char* scorelineNames[] = {
|
||||
QT_TR_NOOP("fall"),
|
||||
QT_TR_NOOP("doit"),
|
||||
QT_TR_NOOP("plop"),
|
||||
QT_TR_NOOP("scoop"),
|
||||
};
|
||||
|
||||
|
||||
//---------------------------------------------------------
|
||||
// ChordLine
|
||||
//---------------------------------------------------------
|
||||
|
@ -390,5 +398,18 @@ void ChordLine::updateGrips(int* grips, int* defaultGrip, QRectF* grip) const
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// accessibleInfo
|
||||
//---------------------------------------------------------
|
||||
|
||||
QString ChordLine::accessibleInfo()
|
||||
{
|
||||
QString rez = Element::accessibleInfo();
|
||||
if(chordLineType() != ChordLineType::NOTYPE)
|
||||
rez = rez + " " + scorelineNames[static_cast<int>(chordLineType()) - 1];
|
||||
return rez;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -64,8 +64,11 @@ class ChordLine : public Element {
|
|||
|
||||
virtual void editDrag(const EditData&);
|
||||
virtual void updateGrips(int*, int*, QRectF*) const override;
|
||||
|
||||
virtual QString accessibleInfo() override;
|
||||
};
|
||||
|
||||
extern const char* scorelineNames[];
|
||||
|
||||
} // namespace Ms
|
||||
#endif
|
||||
|
|
|
@ -925,6 +925,56 @@ void ChordRest::setDurationType(const TDuration& v)
|
|||
_crossMeasure = CrossMeasure::UNKNOWN;
|
||||
}
|
||||
|
||||
QString ChordRest::durationUserName()
|
||||
{
|
||||
QString duration = tr("Duration:");
|
||||
QString tupletType = "";
|
||||
if(tuplet()) {
|
||||
switch (tuplet()->ratio().numerator()) {
|
||||
case 2:
|
||||
tupletType += " " + tr("Duplet");
|
||||
break;
|
||||
case 3:
|
||||
tupletType += " " + tr("Triplet");
|
||||
break;
|
||||
case 4:
|
||||
tupletType += " " + tr("Quadruplet");
|
||||
break;
|
||||
case 5:
|
||||
tupletType += " " + tr("Quinplet");
|
||||
break;
|
||||
case 6:
|
||||
tupletType += " " + tr("Sextuplet");
|
||||
break;
|
||||
case 7:
|
||||
tupletType += " " + tr("Septuplet");
|
||||
break;
|
||||
case 8:
|
||||
tupletType += " " + tr("Octuplet");
|
||||
break;
|
||||
case 9:
|
||||
tupletType += " " + tr("Nontuplet");
|
||||
break;
|
||||
default:
|
||||
tupletType += " " + tr("Custom Tuplet");
|
||||
}
|
||||
}
|
||||
QString dotString = "";
|
||||
|
||||
switch (dots()) {
|
||||
case 1:
|
||||
dotString += " " + tr("Dotted");
|
||||
break;
|
||||
case 2:
|
||||
dotString += " " + tr("Double dotted");
|
||||
break;
|
||||
case 3:
|
||||
dotString += " " + tr("Triple dotted");
|
||||
break;
|
||||
}
|
||||
return duration + tupletType + dotString + " " + durationType().durationTypeUserName() + " " + tr("note");
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// setTrack
|
||||
//---------------------------------------------------------
|
||||
|
@ -1192,5 +1242,49 @@ Element* ChordRest::prevElement()
|
|||
return segment()->lastInPrevSegments(staffIdx());
|
||||
}
|
||||
|
||||
QString ChordRest::accessibleExtraInfo()
|
||||
{
|
||||
QString rez = "";
|
||||
foreach (Articulation* a, articulations())
|
||||
rez = rez + " " + a->screenReaderInfo();
|
||||
|
||||
foreach (Element* l, lyricsList())
|
||||
rez = rez + " " + l->screenReaderInfo();
|
||||
|
||||
if(segment()) {
|
||||
foreach (Element* e, segment()->annotations()) {
|
||||
if (e->staffIdx() == staffIdx() )
|
||||
rez = rez + " " + e->screenReaderInfo();
|
||||
}
|
||||
|
||||
SpannerMap smap = score()->spannerMap();
|
||||
std::vector< ::Interval<Spanner*> > spanners = smap.findOverlapping(tick(), tick());
|
||||
for (std::vector< ::Interval<Spanner*> >::iterator i = spanners.begin(); i < spanners.end(); i++) {
|
||||
::Interval<Spanner*> interval = *i;
|
||||
Spanner* s = interval.value;
|
||||
if (s->type() == Element::Type::VOLTA || //voltas are added for barlines
|
||||
s->type() == Element::Type::TIE ) //ties are added in notes
|
||||
continue;
|
||||
|
||||
Segment* seg = 0;
|
||||
if (s->type() == Element::Type::SLUR) {
|
||||
if(s->tick() == tick() && s->track() == track())
|
||||
rez += " " + tr("Start of %1").arg(s->screenReaderInfo());
|
||||
if(s->tick2() == tick() && s->track2() == track())
|
||||
rez += " " + tr("End of %1").arg(s->screenReaderInfo());
|
||||
}
|
||||
else {
|
||||
if(s->tick() == tick() && s->staffIdx() == staffIdx())
|
||||
rez += " " + tr("Start of %1").arg(s->screenReaderInfo());
|
||||
seg = segment()->next1MM(Segment::Type::ChordRest);
|
||||
if (!seg)
|
||||
continue;
|
||||
if(s->tick2() == seg->tick() && s->staffIdx() == staffIdx())
|
||||
rez += " " + tr("End of %1").arg(s->screenReaderInfo());
|
||||
}
|
||||
}
|
||||
}
|
||||
return rez;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -137,6 +137,7 @@ class ChordRest : public DurationElement {
|
|||
int actualDots() const { return _durationType.dots(); }
|
||||
int durationTypeTicks() { return _crossMeasure == CrossMeasure::FIRST ? _crossMeasureTDur.ticks()
|
||||
: _durationType.ticks(); }
|
||||
QString durationUserName();
|
||||
|
||||
virtual void setTrack(int val);
|
||||
virtual int tick() const;
|
||||
|
@ -161,11 +162,11 @@ class ChordRest : public DurationElement {
|
|||
bool isGraceBefore() const;
|
||||
bool isGraceAfter() const;
|
||||
void writeBeam(Xml& xml);
|
||||
|
||||
Segment* nextSegmentAfterCR(Segment::Type types) const;
|
||||
|
||||
virtual Element* nextElement() override;
|
||||
virtual Element* prevElement() override;
|
||||
virtual QString accessibleExtraInfo() override;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@ const ClefInfo ClefInfo::clefTable[] = {
|
|||
{ "TAB2", "TAB", 5, 0, 0, { 0, 3,-1, 2, 5, 1, 4, 4, 1, 5, 2, 6, 3, 7 }, QT_TRANSLATE_NOOP("clefTable", "Tablature2"), StaffGroup::TAB },
|
||||
};
|
||||
|
||||
|
||||
//---------------------------------------------------------
|
||||
// tag2type
|
||||
//---------------------------------------------------------
|
||||
|
@ -650,5 +651,15 @@ Element* Clef::prevElement()
|
|||
{
|
||||
return segment()->lastInPrevSegments(staffIdx());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// accessibleInfo
|
||||
//---------------------------------------------------------
|
||||
|
||||
QString Clef::accessibleInfo()
|
||||
{
|
||||
return ClefInfo::name(clefType());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ class Segment;
|
|||
|
||||
static const int NO_CLEF = -1000;
|
||||
|
||||
|
||||
//---------------------------------------------------------
|
||||
// ClefType
|
||||
//---------------------------------------------------------
|
||||
|
@ -186,9 +187,9 @@ class Clef : public Element {
|
|||
|
||||
virtual Element* nextElement() override;
|
||||
virtual Element* prevElement() override;
|
||||
QString accessibleInfo() override;
|
||||
};
|
||||
|
||||
|
||||
} // namespace Ms
|
||||
#endif
|
||||
|
||||
|
|
|
@ -516,29 +516,28 @@ QList<TDuration> toDurationList(Fraction l, bool useDots, int maxDots, bool prin
|
|||
// print
|
||||
//---------------------------------------------------------
|
||||
|
||||
void TDuration::print() const
|
||||
QString TDuration::durationTypeUserName() const
|
||||
{
|
||||
qDebug("TDuration(");
|
||||
const char* s = "?";
|
||||
QString s = QObject::tr("Custom");
|
||||
switch(_val) {
|
||||
case DurationType::V_LONG: s = "Long"; break;
|
||||
case DurationType::V_BREVE: s = "Breve"; break;
|
||||
case DurationType::V_WHOLE: s = "Whole"; break;
|
||||
case DurationType::V_HALF: s = "Half"; break;
|
||||
case DurationType::V_QUARTER: s = "Quarter"; break;
|
||||
case DurationType::V_EIGHTH: s = "Eighth"; break;
|
||||
case DurationType::V_16TH: s = "16th"; break;
|
||||
case DurationType::V_32ND: s = "32nd"; break;
|
||||
case DurationType::V_64TH: s = "64th"; break;
|
||||
case DurationType::V_128TH: s = "128th"; break;
|
||||
case DurationType::V_256TH: s = "256th"; break;
|
||||
case DurationType::V_512TH: s = "512th"; break;
|
||||
case DurationType::V_1024TH: s = "1024th"; break;
|
||||
case DurationType::V_ZERO: s = "Zero"; break;
|
||||
case DurationType::V_MEASURE: s = "Measure"; break;
|
||||
case DurationType::V_INVALID: s = "Invalid"; break;
|
||||
case DurationType::V_LONG: s = QObject::tr("Long" ); break;
|
||||
case DurationType::V_BREVE: s = QObject::tr("Breve" ); break;
|
||||
case DurationType::V_WHOLE: s = QObject::tr("Whole" ); break;
|
||||
case DurationType::V_HALF: s = QObject::tr("Half" ); break;
|
||||
case DurationType::V_QUARTER: s = QObject::tr("Quarter"); break;
|
||||
case DurationType::V_EIGHTH: s = QObject::tr("Eighth" ); break;
|
||||
case DurationType::V_16TH: s = QObject::tr("16th" ); break;
|
||||
case DurationType::V_32ND: s = QObject::tr("32nd" ); break;
|
||||
case DurationType::V_64TH: s = QObject::tr("64th" ); break;
|
||||
case DurationType::V_128TH: s = QObject::tr("128th" ); break;
|
||||
case DurationType::V_256TH: s = QObject::tr("256th" ); break;
|
||||
case DurationType::V_512TH: s = QObject::tr("512th" ); break;
|
||||
case DurationType::V_1024TH: s = QObject::tr("1024th" ); break;
|
||||
case DurationType::V_ZERO: s = QObject::tr("Zero" ); break;
|
||||
case DurationType::V_MEASURE: s = QObject::tr("Measure"); break;
|
||||
case DurationType::V_INVALID: s = QObject::tr("Invalid"); break;
|
||||
};
|
||||
qDebug(" %s,dots=%d)", s, _dots);
|
||||
return s;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
|
|
@ -66,7 +66,7 @@ class TDuration {
|
|||
int dots() const { return _dots; }
|
||||
void setDots(int v);
|
||||
Fraction fraction() const;
|
||||
void print() const;
|
||||
QString durationTypeUserName() const;
|
||||
};
|
||||
|
||||
extern QList<TDuration> toDurationList(
|
||||
|
|
|
@ -440,5 +440,14 @@ QVariant Dynamic::propertyDefault(P_ID id) const
|
|||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// accessibleInfo
|
||||
//---------------------------------------------------------
|
||||
|
||||
QString Dynamic::accessibleInfo()
|
||||
{
|
||||
return Element::accessibleInfo() + " " + this->dynamicTypeName();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -86,7 +86,7 @@ class Dynamic : public Text {
|
|||
Segment* segment() const { return (Segment*)parent(); }
|
||||
Measure* measure() const { return (Measure*)parent()->parent(); }
|
||||
|
||||
void setDynamicType(Type val) { _dynamicType = val; }
|
||||
void setDynamicType(Type val) { _dynamicType = val; }
|
||||
void setDynamicType(const QString&);
|
||||
QString dynamicTypeName() const;
|
||||
Type dynamicType() const { return _dynamicType; }
|
||||
|
@ -113,8 +113,9 @@ class Dynamic : public Text {
|
|||
virtual QVariant getProperty(P_ID propertyId) const override;
|
||||
virtual bool setProperty(P_ID propertyId, const QVariant&) override;
|
||||
virtual QVariant propertyDefault(P_ID id) const override;
|
||||
};
|
||||
|
||||
virtual QString accessibleInfo() override;
|
||||
};
|
||||
|
||||
} // namespace Ms
|
||||
|
||||
|
|
|
@ -1943,4 +1943,13 @@ Element* Element::prevElement()
|
|||
}
|
||||
return score()->firstElement();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// accessibleInfo
|
||||
//---------------------------------------------------------
|
||||
|
||||
QString Element::accessibleInfo()
|
||||
{
|
||||
return userName();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,10 +39,12 @@ class TextStyle;
|
|||
class Element;
|
||||
enum class SymId;
|
||||
|
||||
|
||||
//---------------------------------------------------------
|
||||
// ElementFlag
|
||||
//---------------------------------------------------------
|
||||
|
||||
|
||||
enum class ElementFlag : char {
|
||||
DROP_TARGET = 0x2,
|
||||
SELECTABLE = 0x4,
|
||||
|
@ -301,11 +303,9 @@ class Element : public QObject {
|
|||
mutable QRectF _bbox; ///< Bounding box relative to _pos + _userOff
|
||||
///< valid after call to layout()
|
||||
uint _tag; ///< tag bitmask
|
||||
|
||||
protected:
|
||||
Score* _score;
|
||||
QPointF _startDragPosition; ///< used during drag
|
||||
|
||||
public:
|
||||
Element(Score* s = 0);
|
||||
Element(const Element&);
|
||||
|
@ -497,6 +497,8 @@ class Element : public QObject {
|
|||
qreal magS() const;
|
||||
|
||||
bool isText() const;
|
||||
virtual bool isSpanner() const { return false; }
|
||||
virtual bool isSpannerSegment() const { return false; }
|
||||
|
||||
qreal point(const Spatium sp) const { return sp.val() * spatium(); }
|
||||
|
||||
|
@ -573,6 +575,11 @@ class Element : public QObject {
|
|||
virtual Element* prevElement(); //< next-element and prev-element command
|
||||
|
||||
bool concertPitch() const;
|
||||
virtual QString accessibleInfo(); //< used to populate the status bar
|
||||
virtual QString screenReaderInfo() { return accessibleInfo(); } //< by default returns accessibleInfo, but can be overriden
|
||||
// if the screen-reader needs a special string (see note for example)
|
||||
virtual QString accessibleExtraInfo() { return QString(); } //< used to return info that will be appended to accessibleInfo
|
||||
// and passed only to the screen-reader
|
||||
};
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
@ -705,6 +712,8 @@ extern void collectElements(void* data, Element* e);
|
|||
|
||||
} // namespace Ms
|
||||
|
||||
|
||||
|
||||
Q_DECLARE_METATYPE(Ms::Element::Type);
|
||||
Q_DECLARE_METATYPE(Ms::Element::Placement);
|
||||
|
||||
|
|
|
@ -66,5 +66,18 @@ void Fingering::reset()
|
|||
score()->undoChangeProperty(this, P_ID::USER_OFF, no);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// accessibleInfo
|
||||
//---------------------------------------------------------
|
||||
|
||||
QString Fingering::accessibleInfo()
|
||||
{
|
||||
QString rez = Element::accessibleInfo();
|
||||
if (textStyleType() == TextStyleType::STRING_NUMBER) {
|
||||
rez += " " + tr("String number");
|
||||
}
|
||||
return rez + " " + text();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -36,6 +36,8 @@ class Fingering : public Text {
|
|||
virtual void write(Xml&) const override;
|
||||
virtual void read(XmlReader&) override;
|
||||
virtual void reset() override;
|
||||
|
||||
virtual QString accessibleInfo() override;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -572,5 +572,20 @@ void Hairpin::reset()
|
|||
SLine::reset();
|
||||
}
|
||||
|
||||
QString Hairpin::accessibleInfo()
|
||||
{
|
||||
QString rez = SLine::accessibleInfo();
|
||||
switch (hairpinType()) {
|
||||
case Type::CRESCENDO:
|
||||
rez += " " + tr("Crescendo");
|
||||
break;
|
||||
case Type::DECRESCENDO:
|
||||
rez += " " + tr("Descrescendo");
|
||||
break;
|
||||
default:
|
||||
rez += " " + tr("Custom");
|
||||
}
|
||||
return rez;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -130,6 +130,7 @@ class Hairpin : public SLine {
|
|||
virtual void setYoff(qreal) override;
|
||||
virtual void styleChanged() override;
|
||||
virtual void reset() override;
|
||||
virtual QString accessibleInfo() override;
|
||||
};
|
||||
|
||||
} // namespace Ms
|
||||
|
|
|
@ -1452,4 +1452,45 @@ const ParsedChord* Harmony::parsedForm()
|
|||
return _parsedForm;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// accessibleInfo
|
||||
//---------------------------------------------------------
|
||||
|
||||
QString Harmony::accessibleInfo()
|
||||
{
|
||||
return Element::accessibleInfo() + " " + harmonyName();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// screenReaderInfo
|
||||
//---------------------------------------------------------
|
||||
|
||||
QString Harmony::screenReaderInfo()
|
||||
{
|
||||
QString rez = Element::accessibleInfo();
|
||||
if (_rootTpc != Tpc::TPC_INVALID)
|
||||
rez += " " + tpc2name(_rootTpc, NoteSpellingType::STANDARD, false, true);
|
||||
|
||||
if (parsedForm() && !hTextName().isEmpty()) {
|
||||
QString aux = parsedForm()->handle();
|
||||
aux = aux.replace("#", tr("sharp")).replace("<", "");
|
||||
QString extension = "";
|
||||
|
||||
foreach (QString s, aux.split(">", QString::SkipEmptyParts)) {
|
||||
if(!s.contains("blues"))
|
||||
s.replace("b", tr("flat"));
|
||||
extension += s + " ";
|
||||
}
|
||||
rez += " " + extension;
|
||||
}
|
||||
else {
|
||||
rez += " " + hTextName();
|
||||
}
|
||||
|
||||
if (_baseTpc != Tpc::TPC_INVALID)
|
||||
rez += + " / " + tpc2name(_baseTpc, NoteSpellingType::STANDARD, false, true);
|
||||
|
||||
return rez;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -178,6 +178,9 @@ class Harmony : public Text {
|
|||
void setHarmony(const QString& s);
|
||||
virtual QPainterPath shape() const;
|
||||
void calculateBoundingRect();
|
||||
|
||||
virtual QString accessibleInfo() override;
|
||||
virtual QString screenReaderInfo() override;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -21,23 +21,19 @@ namespace Ms {
|
|||
// JumpTypeTable
|
||||
//---------------------------------------------------------
|
||||
|
||||
struct JumpTypeTable {
|
||||
Jump::Type type;
|
||||
TextStyleType textStyleType;
|
||||
const char* text;
|
||||
const char* jumpTo;
|
||||
const char* playUntil;
|
||||
const char* continueAt;
|
||||
const JumpTypeTable jumpTypeTable[] = {
|
||||
{ Jump::Type::DC, TextStyleType::REPEAT_RIGHT, "D.C.", "start", "end", "", QObject::tr("Da Capo") },
|
||||
{ Jump::Type::DC_AL_FINE, TextStyleType::REPEAT_RIGHT, "D.C. al Fine", "start", "fine", "" , QObject::tr("Da Capo al Fine")},
|
||||
{ Jump::Type::DC_AL_CODA, TextStyleType::REPEAT_RIGHT, "D.C. al Coda", "start", "coda", "codab", QObject::tr("Da Capo al Coda")},
|
||||
{ Jump::Type::DS_AL_CODA, TextStyleType::REPEAT_RIGHT, "D.S. al Coda", "segno", "coda", "codab", QObject::tr("D.S. al Coda") },
|
||||
{ Jump::Type::DS_AL_FINE, TextStyleType::REPEAT_RIGHT, "D.S. al Fine", "segno", "fine", "", QObject::tr("D.S. al Fine") },
|
||||
{ Jump::Type::DS, TextStyleType::REPEAT_RIGHT, "D.S.", "segno", "end", "", QObject::tr("D.S.") }
|
||||
};
|
||||
|
||||
static const JumpTypeTable jumpTypeTable[] = {
|
||||
{ Jump::Type::DC, TextStyleType::REPEAT_RIGHT, "D.C.", "start", "end", "" },
|
||||
{ Jump::Type::DC_AL_FINE, TextStyleType::REPEAT_RIGHT, "D.C. al Fine", "start", "fine", "" },
|
||||
{ Jump::Type::DC_AL_CODA, TextStyleType::REPEAT_RIGHT, "D.C. al Coda", "start", "coda", "codab" },
|
||||
{ Jump::Type::DS_AL_CODA, TextStyleType::REPEAT_RIGHT, "D.S. al Coda", "segno", "coda", "codab" },
|
||||
{ Jump::Type::DS_AL_FINE, TextStyleType::REPEAT_RIGHT, "D.S. al Fine", "segno", "fine", "" },
|
||||
{ Jump::Type::DS, TextStyleType::REPEAT_RIGHT, "D.S.", "segno", "end", "" }
|
||||
};
|
||||
int jumpTypeTableSize()
|
||||
{
|
||||
return sizeof(jumpTypeTable)/sizeof(JumpTypeTable);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Jump
|
||||
|
@ -82,6 +78,14 @@ Jump::Type Jump::jumpType() const
|
|||
return Type::USER;
|
||||
}
|
||||
|
||||
QString Jump::jumpTypeUserName() const
|
||||
{
|
||||
int idx = static_cast<int>(this->jumpType());
|
||||
if(idx < jumpTypeTableSize())
|
||||
return jumpTypeTable[idx].userText;
|
||||
return QString("Custom");
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// read
|
||||
//---------------------------------------------------------
|
||||
|
@ -224,5 +228,14 @@ Element* Jump::prevElement()
|
|||
return nextElement();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// accessibleInfo
|
||||
//---------------------------------------------------------
|
||||
|
||||
QString Jump::accessibleInfo()
|
||||
{
|
||||
return Element::accessibleInfo() + " " + this->jumpTypeUserName();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ namespace Ms {
|
|||
// @P jumpType Ms::Jump::Type (DC, DC_AL_FINE, DC_AL_CODA, DS_AL_CODA, DS_AL_FINE, DS, USER) (read only)
|
||||
//---------------------------------------------------------
|
||||
|
||||
|
||||
class Jump : public Text {
|
||||
Q_OBJECT
|
||||
|
||||
|
@ -55,6 +56,7 @@ class Jump : public Text {
|
|||
|
||||
void setJumpType(Type t);
|
||||
Type jumpType() const;
|
||||
QString jumpTypeUserName() const;
|
||||
|
||||
virtual Jump* clone() const { return new Jump(*this); }
|
||||
virtual Element::Type type() const { return Element::Type::JUMP; }
|
||||
|
@ -79,10 +81,26 @@ class Jump : public Text {
|
|||
virtual QVariant getProperty(P_ID propertyId) const;
|
||||
virtual bool setProperty(P_ID propertyId, const QVariant&);
|
||||
virtual QVariant propertyDefault(P_ID) const;
|
||||
|
||||
Element* nextElement() override;
|
||||
Element* prevElement() override;
|
||||
virtual QString accessibleInfo() override;
|
||||
};
|
||||
|
||||
|
||||
struct JumpTypeTable {
|
||||
Jump::Type type;
|
||||
TextStyleType textStyleType;
|
||||
const char* text;
|
||||
const char* jumpTo;
|
||||
const char* playUntil;
|
||||
const char* continueAt;
|
||||
QString userText;
|
||||
};
|
||||
|
||||
extern const JumpTypeTable jumpTypeTable[];
|
||||
int jumpTypeTableSize();
|
||||
|
||||
} // namespace Ms
|
||||
|
||||
Q_DECLARE_METATYPE(Ms::Jump::Type);
|
||||
|
|
|
@ -524,6 +524,26 @@ Element* KeySig::prevElement()
|
|||
return segment()->lastInPrevSegments(staffIdx());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// accessibleInfo
|
||||
//---------------------------------------------------------
|
||||
|
||||
QString KeySig::accessibleInfo()
|
||||
{
|
||||
QString keySigType;
|
||||
if (isCustom())
|
||||
keySigType = tr("Custom");
|
||||
|
||||
if (key() == Key::C)
|
||||
return keyNames[14];
|
||||
int keyInt = static_cast<int>(key());
|
||||
if (keyInt < 0)
|
||||
keySigType = keyNames[(7 + keyInt) * 2 + 1];
|
||||
else
|
||||
keySigType = keyNames[(keyInt - 1) * 2];
|
||||
return Element::accessibleInfo() + " " + keySigType;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -93,11 +93,11 @@ class KeySig : public Element {
|
|||
|
||||
virtual Element* nextElement() override;
|
||||
virtual Element* prevElement() override;
|
||||
virtual QString accessibleInfo() override;
|
||||
};
|
||||
|
||||
extern const char* keyNames[];
|
||||
|
||||
|
||||
} // namespace Ms
|
||||
#endif
|
||||
|
||||
|
|
|
@ -18,6 +18,23 @@
|
|||
|
||||
namespace Ms {
|
||||
|
||||
//must be in sync with Marker::Type enum
|
||||
const MarkerTypeItem markerTypeTable[] = {
|
||||
{ Marker::Type::SEGNO , QObject::tr("Segno") },
|
||||
{ Marker::Type::VARSEGNO, QObject::tr("Segno Variation")},
|
||||
{ Marker::Type::CODA , QObject::tr("Coda") },
|
||||
{ Marker::Type::VARCODA , QObject::tr("Varied coda") },
|
||||
{ Marker::Type::CODETTA , QObject::tr("Codetta") },
|
||||
{ Marker::Type::FINE , QObject::tr("Fine") },
|
||||
{ Marker::Type::TOCODA , QObject::tr("To Coda") },
|
||||
{ Marker::Type::USER , QObject::tr("Custom") }
|
||||
};
|
||||
|
||||
int markerTypeTableSize()
|
||||
{
|
||||
return sizeof(markerTypeTable)/sizeof(MarkerTypeItem) - 1; //-1 for the user defined
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Marker
|
||||
//---------------------------------------------------------
|
||||
|
@ -88,6 +105,11 @@ void Marker::setMarkerType(Type t)
|
|||
setText(txt);
|
||||
}
|
||||
|
||||
QString Marker::markerTypeUserName()
|
||||
{
|
||||
return markerTypeTable[static_cast<int>(_markerType)].name;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// styleChanged
|
||||
//---------------------------------------------------------
|
||||
|
@ -274,6 +296,7 @@ QVariant Marker::propertyDefault(P_ID propertyId) const
|
|||
return Text::propertyDefault(propertyId);
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------
|
||||
// nextElement
|
||||
//---------------------------------------------------------
|
||||
|
@ -303,5 +326,14 @@ Element* Marker::prevElement()
|
|||
return nextElement();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// accessibleInfo
|
||||
//---------------------------------------------------------
|
||||
|
||||
QString Marker::accessibleInfo()
|
||||
{
|
||||
return Element::accessibleInfo() + " " + markerTypeUserName();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ class Marker : public Text {
|
|||
USER
|
||||
};
|
||||
|
||||
|
||||
private:
|
||||
Type _markerType;
|
||||
QString _label; ///< referenced from Jump() element
|
||||
|
@ -55,6 +56,7 @@ class Marker : public Text {
|
|||
|
||||
void setMarkerType(Type t);
|
||||
Type markerType() const { return _markerType; }
|
||||
QString markerTypeUserName();
|
||||
|
||||
virtual Marker* clone() const override { return new Marker(*this); }
|
||||
virtual Element::Type type() const override { return Element::Type::MARKER; }
|
||||
|
@ -80,8 +82,16 @@ class Marker : public Text {
|
|||
|
||||
virtual Element* nextElement() override;
|
||||
virtual Element* prevElement() override;
|
||||
virtual QString accessibleInfo() override;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
Marker::Type type;
|
||||
QString name;
|
||||
} MarkerTypeItem;
|
||||
|
||||
extern const MarkerTypeItem markerTypeTable[];
|
||||
int markerTypeTableSize();
|
||||
} // namespace Ms
|
||||
|
||||
Q_DECLARE_METATYPE(Ms::Marker::Type);
|
||||
|
|
|
@ -4038,5 +4038,14 @@ Element* Measure::prevElement(int staff)
|
|||
return score()->lastElement();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// accessibleInfo
|
||||
//---------------------------------------------------------
|
||||
|
||||
QString Measure::accessibleInfo()
|
||||
{
|
||||
return Element::accessibleInfo() + " " + QString::number(no() + 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -323,6 +323,7 @@ class Measure : public MeasureBase {
|
|||
|
||||
Element* nextElement(int staff);
|
||||
Element* prevElement(int staff);
|
||||
virtual QString accessibleInfo() override;
|
||||
};
|
||||
|
||||
} // namespace Ms
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
// as published by the Free Software Foundation and appearing in
|
||||
// the file LICENCE.GPL
|
||||
//=============================================================================
|
||||
|
||||
#include <QLabel>
|
||||
#include <QList>
|
||||
/**
|
||||
\file
|
||||
Implementation of classes Note and ShadowNote.
|
||||
|
@ -416,6 +417,13 @@ int Note::tpc() const
|
|||
return _tpc[concertPitchIdx()];
|
||||
}
|
||||
|
||||
QString Note::tpcUserName(bool explicitAccidental)
|
||||
{
|
||||
QString pitch = tr("Pitch: %1").arg(tpc2name(tpc(), NoteSpellingType::STANDARD, false, explicitAccidental));
|
||||
QString octave = QString::number((this->pitch() / 12) - 2);
|
||||
return pitch + (explicitAccidental ? " " : "") + octave;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// transposeTpc
|
||||
// return transposed tpc
|
||||
|
@ -1735,6 +1743,32 @@ NoteType Note::noteType() const
|
|||
return chord()->noteType();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// noteTypeUserName
|
||||
//---------------------------------------------------------
|
||||
|
||||
QString Note::noteTypeUserName()
|
||||
{
|
||||
switch (noteType()) {
|
||||
case NoteType::ACCIACCATURA:
|
||||
return tr("Accaciatura");
|
||||
case NoteType::APPOGGIATURA:
|
||||
return tr("Appoggiatura");
|
||||
case NoteType::GRACE8_AFTER:
|
||||
case NoteType::GRACE16_AFTER:
|
||||
case NoteType::GRACE32_AFTER:
|
||||
return tr("Grace note after");
|
||||
case NoteType::GRACE4:
|
||||
case NoteType::GRACE16:
|
||||
case NoteType::GRACE32:
|
||||
return tr("Grace note before");
|
||||
case NoteType::INVALID:
|
||||
return tr("Invalid note");
|
||||
default:
|
||||
return tr("Note");
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// pagePos
|
||||
//---------------------------------------------------------
|
||||
|
@ -2370,6 +2404,64 @@ void Note::setScore(Score* s)
|
|||
_tieFor->setScore(s);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// accessibleInfo
|
||||
//---------------------------------------------------------
|
||||
|
||||
QString Note::accessibleInfo()
|
||||
{
|
||||
QString duration = chord()->durationUserName();
|
||||
QString voice = tr("Voice: %1").arg(QString::number(track() % VOICES + 1));
|
||||
return noteTypeUserName() + " " + tpcUserName(false) +" " + duration + " " + (chord()->isGrace() ? "" : voice);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// screenReaderInfo
|
||||
//---------------------------------------------------------
|
||||
|
||||
QString Note::screenReaderInfo()
|
||||
{
|
||||
QString duration = chord()->durationUserName();
|
||||
QString voice = tr("Voice: %1").arg(QString::number(track() % VOICES + 1));
|
||||
return noteTypeUserName() + " " + tpcUserName(true) +" " + duration + " " + (chord()->isGrace() ? "" : voice);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// accessibleExtraInfo
|
||||
//---------------------------------------------------------
|
||||
|
||||
QString Note::accessibleExtraInfo()
|
||||
{
|
||||
QString rez = "";
|
||||
if (accidental()) {
|
||||
rez += " " + accidental()->screenReaderInfo();
|
||||
}
|
||||
if (!el().isEmpty()) {
|
||||
foreach (Element* e, el()) {
|
||||
rez = rez + " " + e->screenReaderInfo();
|
||||
}
|
||||
}
|
||||
if (tieFor())
|
||||
rez += " " + tr("Start of %1").arg(tieFor()->screenReaderInfo());
|
||||
|
||||
if (tieBack())
|
||||
rez += " " + tr("End of %1").arg(tieBack()->screenReaderInfo());
|
||||
|
||||
if (!spannerFor().isEmpty()) {
|
||||
foreach (Spanner* s, spannerFor()) {
|
||||
rez += " " + tr("Start of %1").arg(s->screenReaderInfo());
|
||||
}
|
||||
}
|
||||
if (!spannerBack().isEmpty()) {
|
||||
foreach (Spanner* s, spannerBack()) {
|
||||
rez += " " + tr("End of %2").arg(s->screenReaderInfo());
|
||||
}
|
||||
}
|
||||
|
||||
rez = rez + " " + chord()->accessibleExtraInfo();
|
||||
return rez;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// noteVal
|
||||
//---------------------------------------------------------
|
||||
|
|
|
@ -285,6 +285,7 @@ class Note : public Element {
|
|||
int tpc() const;
|
||||
int tpc1() const { return _tpc[0]; } // non transposed tpc
|
||||
int tpc2() const { return _tpc[1]; } // transposed tpc
|
||||
QString tpcUserName(bool explicitAccidental = false);
|
||||
|
||||
void setTpc(int v);
|
||||
void setTpc1(int v) { _tpc[0] = v; }
|
||||
|
@ -330,7 +331,6 @@ class Note : public Element {
|
|||
|
||||
Chord* chord() const { return (Chord*)parent(); }
|
||||
void setChord(Chord* a) { setParent((Element*)a); }
|
||||
|
||||
void draw(QPainter*) const;
|
||||
|
||||
void read(XmlReader&);
|
||||
|
@ -345,6 +345,7 @@ class Note : public Element {
|
|||
void setDotsHidden(bool val) { _dotsHidden = val; }
|
||||
|
||||
NoteType noteType() const;
|
||||
QString noteTypeUserName();
|
||||
|
||||
ElementList el() { return _el; }
|
||||
const ElementList el() const { return _el; }
|
||||
|
@ -423,6 +424,9 @@ class Note : public Element {
|
|||
|
||||
virtual Element* nextElement() override;
|
||||
virtual Element* prevElement() override;
|
||||
virtual QString accessibleInfo() override;
|
||||
virtual QString screenReaderInfo() override;
|
||||
virtual QString accessibleExtraInfo() override;
|
||||
};
|
||||
|
||||
// extern const SymId noteHeads[2][int(NoteHead::Group::HEAD_GROUPS)][int(NoteHead::Type::HEAD_TYPES)];
|
||||
|
|
|
@ -540,5 +540,14 @@ void Ottava::reset()
|
|||
|
||||
TextLine::reset();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// accessibleInfo
|
||||
//---------------------------------------------------------
|
||||
|
||||
QString Ottava::accessibleInfo()
|
||||
{
|
||||
return Element::accessibleInfo() + " " + ottavaDefault[static_cast<int>(ottavaType())].name;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -115,6 +115,8 @@ class Ottava : public TextLine {
|
|||
virtual void setYoff(qreal) override;
|
||||
virtual void styleChanged() override;
|
||||
virtual void reset() override;
|
||||
|
||||
virtual QString accessibleInfo() override;
|
||||
};
|
||||
|
||||
} // namespace Ms
|
||||
|
|
|
@ -225,34 +225,34 @@ int tpc2alterByKey(int tpc, Key key) {
|
|||
// return note name
|
||||
//---------------------------------------------------------
|
||||
|
||||
QString tpc2name(int tpc, NoteSpellingType spelling, bool lowerCase)
|
||||
QString tpc2name(int tpc, NoteSpellingType spelling, bool lowerCase, bool explicitAccidental)
|
||||
{
|
||||
QString s;
|
||||
QString acc;
|
||||
tpc2name(tpc, spelling, lowerCase, s, acc);
|
||||
return s + acc;
|
||||
tpc2name(tpc, spelling, lowerCase, s, acc, explicitAccidental);
|
||||
return s + (explicitAccidental ? " " : "") + acc;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// tpc2name
|
||||
//---------------------------------------------------------
|
||||
|
||||
void tpc2name(int tpc, NoteSpellingType spelling, bool lowerCase, QString& s, QString& acc)
|
||||
void tpc2name(int tpc, NoteSpellingType spelling, bool lowerCase, QString& s, QString& acc, bool explicitAccidental)
|
||||
{
|
||||
int n;
|
||||
tpc2name(tpc, spelling, lowerCase, s, n);
|
||||
switch (n) {
|
||||
case -2: acc = "bb" ; break;
|
||||
case -2: acc = explicitAccidental ? QObject::tr("double flat") : "bb" ; break;
|
||||
case -1:
|
||||
if (spelling != NoteSpellingType::GERMAN)
|
||||
acc = "b";
|
||||
acc = explicitAccidental ? QObject::tr("flat") : "b";
|
||||
else
|
||||
// render flats as "es" except for A and E, which get "s"
|
||||
acc = (tpc == 10 || tpc == 11) ? "s" : "es";
|
||||
break;
|
||||
case 0: acc = ""; break;
|
||||
case 1: acc = (spelling != NoteSpellingType::GERMAN) ? "#" : "is"; break;
|
||||
case 2: acc = "##"; break;
|
||||
case 1: acc = (spelling != NoteSpellingType::GERMAN) ? (explicitAccidental ? QObject::tr("sharp") : "#") : "is"; break;
|
||||
case 2: acc = explicitAccidental ? QObject::tr("double sharp") : "##"; break;
|
||||
default:
|
||||
qDebug("tpc2name(%d): acc %d", tpc, n);
|
||||
acc = "";
|
||||
|
|
|
@ -60,8 +60,8 @@ 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, NoteSpellingType spelling, bool lowerCase);
|
||||
extern void tpc2name(int tpc, NoteSpellingType spelling, bool lowerCase, QString& s, QString& acc);
|
||||
extern QString tpc2name(int tpc, NoteSpellingType spelling, bool lowerCase, bool explicitAccidental = false);
|
||||
extern void tpc2name(int tpc, NoteSpellingType spelling, bool lowerCase, QString& s, QString& acc, bool explicitAccidental = false);
|
||||
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);
|
||||
|
|
|
@ -78,5 +78,14 @@ Fraction RepeatMeasure::duration() const
|
|||
return Fraction(0, 1);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// accessibleInfo
|
||||
//---------------------------------------------------------
|
||||
|
||||
QString RepeatMeasure::accessibleInfo()
|
||||
{
|
||||
return Element::accessibleInfo();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,8 @@ class RepeatMeasure : public Rest {
|
|||
virtual void draw(QPainter*) const;
|
||||
virtual void layout();
|
||||
virtual Fraction duration() const;
|
||||
|
||||
virtual QString accessibleInfo();
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -624,5 +624,16 @@ qreal Rest::stemPosX() const
|
|||
else
|
||||
return bbox().left();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// accessibleInfo
|
||||
//---------------------------------------------------------
|
||||
|
||||
QString Rest::accessibleInfo()
|
||||
{
|
||||
QString voice = tr("Voice: %1").arg(QString::number(track() % VOICES + 1));
|
||||
return Element::accessibleInfo() + " " + durationUserName() + " " + voice ;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -49,7 +49,6 @@ class Rest : public ChordRest {
|
|||
|
||||
virtual Rest* clone() const override { return new Rest(*this, false); }
|
||||
virtual Rest* linkedClone() const { return new Rest(*this, true); }
|
||||
|
||||
virtual Measure* measure() const override { return parent() ? (Measure*)(parent()->parent()) : 0; }
|
||||
virtual qreal mag() const override;
|
||||
virtual void draw(QPainter*) const override;
|
||||
|
@ -75,8 +74,9 @@ class Rest : public ChordRest {
|
|||
virtual QPointF stemPos() const;
|
||||
virtual qreal stemPosX() const;
|
||||
virtual QPointF stemPosBeam() const;
|
||||
};
|
||||
|
||||
virtual QString accessibleInfo() override;
|
||||
};
|
||||
|
||||
} // namespace Ms
|
||||
#endif
|
||||
|
|
|
@ -337,6 +337,7 @@ Score::Score()
|
|||
_tempomap = new TempoMap;
|
||||
_sigmap = new TimeSigMap();
|
||||
_style = *(MScore::defaultStyle());
|
||||
accInfo = tr("No selection");
|
||||
}
|
||||
|
||||
Score::Score(const MStyle* s)
|
||||
|
@ -347,6 +348,7 @@ Score::Score(const MStyle* s)
|
|||
_tempomap = new TempoMap;
|
||||
_sigmap = new TimeSigMap();
|
||||
_style = *s;
|
||||
accInfo = tr("No selection");
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -383,6 +385,7 @@ Score::Score(Score* parent)
|
|||
}
|
||||
|
||||
_synthesizerState = parent->_synthesizerState;
|
||||
accInfo = tr("No selection");
|
||||
}
|
||||
|
||||
Score::Score(Score* parent, const MStyle* s)
|
||||
|
@ -391,6 +394,7 @@ Score::Score(Score* parent, const MStyle* s)
|
|||
_parentScore = parent;
|
||||
init();
|
||||
_style = *s;
|
||||
accInfo = tr("No selection");
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
@ -2710,8 +2714,9 @@ void Score::selectSingle(Element* e, int staffIdx)
|
|||
_selection.add(e);
|
||||
_is.setTrack(e->track());
|
||||
selState = SelState::LIST;
|
||||
if (e->type() == Element::Type::NOTE)
|
||||
if (e->type() == Element::Type::NOTE) {
|
||||
e = e->parent();
|
||||
}
|
||||
if (e->type() == Element::Type::REST || e->type() == Element::Type::CHORD) {
|
||||
_is.setLastSegment(_is.segment());
|
||||
_is.setSegment(static_cast<ChordRest*>(e)->segment());
|
||||
|
|
|
@ -374,6 +374,7 @@ class Score : public QObject {
|
|||
PlayMode _playMode;
|
||||
|
||||
qreal _noteHeadWidth;
|
||||
QString accInfo; ///< information used by the screen-reader
|
||||
|
||||
//------------------
|
||||
|
||||
|
@ -989,6 +990,8 @@ class Score : public QObject {
|
|||
Element* lastElement();
|
||||
|
||||
void cmdInsertClef(Clef* clef, ChordRest* cr);
|
||||
void setAccessibleInfo(QString s) { accInfo = s.remove(":"); }
|
||||
QString accessibleInfo() { return accInfo; }
|
||||
|
||||
friend class ChangeSynthesizerState;
|
||||
friend class Chord;
|
||||
|
|
|
@ -1166,4 +1166,59 @@ Element* Segment::lastElement(int staff)
|
|||
return 0;
|
||||
}
|
||||
|
||||
QString Segment::accessibleExtraInfo()
|
||||
{
|
||||
QString rez = "";
|
||||
if (!this->annotations().empty()) {
|
||||
rez = rez + tr("Annotations: ");
|
||||
foreach (Element* a, this->annotations()) {
|
||||
switch(a->type()) {
|
||||
case Element::Type::DYNAMIC:
|
||||
//they are added in the chordrest, because they are for only one staff
|
||||
break;
|
||||
default:
|
||||
rez = rez + " " + a->accessibleInfo();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QString startSpanners = "";
|
||||
QString endSpanners = "";
|
||||
SpannerMap smap = score()->spannerMap();
|
||||
std::vector< ::Interval<Spanner*> > spanners = smap.findOverlapping(this->tick(), this->tick());
|
||||
for (std::vector< ::Interval<Spanner*> >::iterator i = spanners.begin(); i < spanners.end(); i++) {
|
||||
::Interval<Spanner*> interval = *i;
|
||||
Spanner* s = interval.value;
|
||||
if (this->segmentType() == Segment::Type::EndBarLine ||
|
||||
this->segmentType() == Segment::Type::BarLine ||
|
||||
this->segmentType() == Segment::Type::StartRepeatBarLine) {
|
||||
if (s->type() != Element::Type::VOLTA)
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
if (s->type() == Element::Type::VOLTA ||
|
||||
s->type() == Element::Type::TIE ) //ties are added in Note
|
||||
continue;
|
||||
}
|
||||
|
||||
if (s->tick() == this->tick())
|
||||
startSpanners += tr("Start of ") + s->accessibleInfo();
|
||||
|
||||
Segment* seg = 0;
|
||||
switch (s->type()) {
|
||||
case Element::Type::VOLTA:
|
||||
case Element::Type::SLUR:
|
||||
seg = this;
|
||||
break;
|
||||
default:
|
||||
seg = this->next1MM(Segment::Type::ChordRest);
|
||||
break;
|
||||
}
|
||||
|
||||
if (seg && s->tick2() == seg->tick())
|
||||
endSpanners += tr("End of ") + s->accessibleInfo();
|
||||
}
|
||||
return rez + " " + startSpanners + " " + endSpanners;
|
||||
}
|
||||
|
||||
} // namespace Ms
|
||||
|
|
|
@ -201,7 +201,7 @@ public:
|
|||
bool operator<(const Segment&) const;
|
||||
bool operator>(const Segment&) const;
|
||||
|
||||
|
||||
virtual QString accessibleExtraInfo() override;
|
||||
Element* firstInNextSegments(int activeStaff); //<
|
||||
Element* lastInPrevSegments(int activeStaff); //<
|
||||
Element* firstElement(int staff); //< These methods are used for navigation
|
||||
|
|
|
@ -190,6 +190,15 @@ Element* SpannerSegment::prevElement()
|
|||
return spanner()->prevElement();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// accessibleInfo
|
||||
//---------------------------------------------------------
|
||||
|
||||
QString SpannerSegment::accessibleInfo()
|
||||
{
|
||||
return spanner()->accessibleInfo();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Spanner
|
||||
//---------------------------------------------------------
|
||||
|
|
|
@ -77,8 +77,11 @@ class SpannerSegment : public Element {
|
|||
virtual void reset() override;
|
||||
virtual void setSelected(bool f) override;
|
||||
virtual void setVisible(bool f) override;
|
||||
|
||||
virtual Element* nextElement() override;
|
||||
virtual Element* prevElement() override;
|
||||
virtual bool isSpannerSegment() const override { return true; }
|
||||
virtual QString accessibleInfo() override;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
|
@ -178,6 +181,8 @@ class Spanner : public Element {
|
|||
virtual Element* nextElement() override;
|
||||
virtual Element* prevElement() override;
|
||||
|
||||
virtual bool isSpanner() const override { return true; }
|
||||
|
||||
friend class SpannerSegment;
|
||||
};
|
||||
|
||||
|
|
|
@ -252,5 +252,31 @@ void TempoText::layout()
|
|||
}
|
||||
}
|
||||
|
||||
QString TempoText::accessibleInfo()
|
||||
{
|
||||
TDuration t;
|
||||
int len;
|
||||
int x = findTempoDuration(text(), len, t);
|
||||
QString dots;
|
||||
|
||||
switch (t.dots()) {
|
||||
case 1: dots = tr("Dotted");
|
||||
break;
|
||||
case 2: dots = tr("Double dotted");
|
||||
break;
|
||||
case 3: dots = tr("Triple dotted");
|
||||
break;
|
||||
default:
|
||||
dots = "";
|
||||
break;
|
||||
}
|
||||
|
||||
QString bpm = text().split(" = ").back();
|
||||
if(x != -1)
|
||||
return Element::accessibleInfo() + dots + " " + t.durationTypeUserName() + " " + tr("note = %1").arg(bpm);
|
||||
else
|
||||
return Text::accessibleInfo();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -60,6 +60,7 @@ class TempoText : public Text {
|
|||
QVariant getProperty(P_ID propertyId) const override;
|
||||
bool setProperty(P_ID propertyId, const QVariant&) override;
|
||||
QVariant propertyDefault(P_ID id) const override;
|
||||
virtual QString accessibleInfo() override;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -2504,5 +2504,38 @@ QString Text::convertToHtml(const QString& s, const TextStyle& st)
|
|||
QString family = st.family();
|
||||
return QString("<html><body style=\"font-family:'%1'; font-size:%2pt;\">%3</body></html>").arg(family).arg(size).arg(s);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// accessibleInfo
|
||||
//---------------------------------------------------------
|
||||
|
||||
QString Text::accessibleInfo()
|
||||
{
|
||||
QString rez;
|
||||
switch (textStyleType()) {
|
||||
case TextStyleType::TITLE:
|
||||
rez = tr ("Title");
|
||||
break;
|
||||
case TextStyleType::SUBTITLE:
|
||||
rez = tr ("Subtitle");
|
||||
break;
|
||||
case TextStyleType::COMPOSER:
|
||||
rez = tr("Composer");
|
||||
break;
|
||||
case TextStyleType::POET:
|
||||
rez = tr ("Poet");
|
||||
break;
|
||||
case TextStyleType::TRANSLATOR:
|
||||
rez = tr ("Translator");
|
||||
break;
|
||||
case TextStyleType::MEASURE_NUMBER:
|
||||
rez = tr ("Measure number");
|
||||
break;
|
||||
default:
|
||||
rez = Element::accessibleInfo();
|
||||
break;
|
||||
}
|
||||
return rez + " " + text();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -303,6 +303,7 @@ class Text : public Element {
|
|||
static QString convertToHtml(const QString&, const TextStyle&);
|
||||
|
||||
void undoSetText(const QString& s) { undoChangeProperty(P_ID::TEXT, s); }
|
||||
virtual QString accessibleInfo() override;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -565,5 +565,23 @@ Element* TimeSig::prevElement()
|
|||
return segment()->lastInPrevSegments(staffIdx());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// accessibleInfo
|
||||
//---------------------------------------------------------
|
||||
|
||||
QString TimeSig::accessibleInfo()
|
||||
{
|
||||
QString timeSigString;
|
||||
switch (timeSigType()) {
|
||||
case TimeSigType::FOUR_FOUR:
|
||||
timeSigString = tr("Common time");
|
||||
case TimeSigType::ALLA_BREVE:
|
||||
timeSigString = tr("Cut time");
|
||||
default:
|
||||
timeSigString = tr("%1/%2 time").arg(QString::number(numerator())).arg(QString::number(denominator()));
|
||||
}
|
||||
return Element::accessibleInfo() + " " + timeSigString;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -137,9 +137,9 @@ class TimeSig : public Element {
|
|||
|
||||
virtual Element* nextElement();
|
||||
virtual Element* prevElement();
|
||||
virtual QString accessibleInfo() override;
|
||||
};
|
||||
|
||||
|
||||
} // namespace Ms
|
||||
#endif
|
||||
|
||||
|
|
|
@ -338,10 +338,23 @@ Fraction Tremolo::tremoloLen() const
|
|||
return f;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// subtypeName
|
||||
//---------------------------------------------------------
|
||||
|
||||
QString Tremolo::subtypeName() const
|
||||
{
|
||||
return tremoloName[subtype() - int(TremoloType::R8)];
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// accessibleInfo
|
||||
//---------------------------------------------------------
|
||||
|
||||
QString Tremolo::accessibleInfo()
|
||||
{
|
||||
return Element::accessibleInfo() + " " + subtypeName();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -78,6 +78,8 @@ class Tremolo : public Element {
|
|||
Fraction tremoloLen() const;
|
||||
bool twoNotes() const { return tremoloType() > TremoloType::R64; } // is it a two note tremolo?
|
||||
int lines() const { return _lines; }
|
||||
|
||||
virtual QString accessibleInfo() override;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -23,6 +23,20 @@
|
|||
|
||||
namespace Ms {
|
||||
|
||||
|
||||
// must be in sync with Trill::Type
|
||||
const TrillTableItem trillTable[] = {
|
||||
{ Trill::Type::TRILL_LINE, "trill", QObject::tr("Trill line") },
|
||||
{ Trill::Type::UPPRALL_LINE, "upprall", QObject::tr("Upprall line") },
|
||||
{ Trill::Type::DOWNPRALL_LINE, "downprall", QObject::tr("Downprall line") },
|
||||
{ Trill::Type::PRALLPRALL_LINE, "prallprall", QObject::tr("Prallprall line") },
|
||||
{ Trill::Type::PURE_LINE , "pure", QObject::tr("Wavy line") }
|
||||
};
|
||||
|
||||
int trillTableSize() {
|
||||
return sizeof(trillTable)/sizeof(TrillTableItem);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// draw
|
||||
//---------------------------------------------------------
|
||||
|
@ -414,6 +428,15 @@ QString Trill::trillTypeName() const
|
|||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// trillTypeName
|
||||
//---------------------------------------------------------
|
||||
|
||||
QString Trill::trillTypeUserName()
|
||||
{
|
||||
return trillTable[static_cast<int>(trillType())].userName;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// scanElements
|
||||
//---------------------------------------------------------
|
||||
|
@ -493,5 +516,13 @@ void Trill::setYoff(qreal val)
|
|||
rUserYoffset() += (val - score()->styleS(StyleIdx::trillY).val()) * spatium();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// accessibleInfo
|
||||
//---------------------------------------------------------
|
||||
|
||||
QString Trill::accessibleInfo()
|
||||
{
|
||||
return Element::accessibleInfo() + " " + trillTypeUserName();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -92,6 +92,7 @@ class Trill : public SLine {
|
|||
void setTrillType(Type tt) { _trillType = tt; }
|
||||
Type trillType() const { return _trillType; }
|
||||
QString trillTypeName() const;
|
||||
QString trillTypeUserName();
|
||||
Accidental* accidental() const { return _accidental; }
|
||||
void setAccidental(Accidental* a) { _accidental = a; }
|
||||
|
||||
|
@ -102,8 +103,18 @@ class Trill : public SLine {
|
|||
virtual bool setProperty(P_ID propertyId, const QVariant&) override;
|
||||
virtual QVariant propertyDefault(P_ID) const override;
|
||||
virtual void setYoff(qreal) override;
|
||||
|
||||
virtual QString accessibleInfo() override;
|
||||
};
|
||||
|
||||
struct TrillTableItem {
|
||||
Trill::Type type;
|
||||
const char* name;
|
||||
QString userName;
|
||||
};
|
||||
|
||||
extern const TrillTableItem trillTable[];
|
||||
extern int trillTableSize();
|
||||
|
||||
} // namespace Ms
|
||||
|
||||
|
|
|
@ -412,5 +412,12 @@ void Volta::reset()
|
|||
TextLine::reset();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// accessibleInfo
|
||||
//---------------------------------------------------------
|
||||
|
||||
QString Volta::accessibleInfo(){
|
||||
return Element::accessibleInfo() + " " + text();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -97,6 +97,7 @@ private:
|
|||
virtual void setYoff(qreal);
|
||||
virtual void reset() override;
|
||||
virtual bool systemFlag() const override { return true; }
|
||||
virtual QString accessibleInfo() override;
|
||||
};
|
||||
|
||||
} // namespace Ms
|
||||
|
|
|
@ -152,8 +152,7 @@ QT4_WRAP_CPP (mocs
|
|||
paletteBoxButton.h pathlistdialog.h exampleview.h noteGroups.h inspector/inspectorTextLine.h
|
||||
importmidi_panel.h importmidi_delegate.h importmidi_view.h
|
||||
debugger/debugger.h
|
||||
resourceManager.h downloadUtils.h accessibletoolbutton.h
|
||||
|
||||
resourceManager.h downloadUtils.h accessibletoolbutton.h scoreaccessibility.h
|
||||
${OMR_MOCS}
|
||||
${SCRIPT_MOCS}
|
||||
)
|
||||
|
@ -278,7 +277,7 @@ add_executable ( ${ExecutableName}
|
|||
importmidi_simplify.cpp importmidi_voice.cpp importmidi_view.cpp
|
||||
resourceManager.cpp downloadUtils.cpp
|
||||
textcursor.cpp
|
||||
continuouspanel.cpp accessibletoolbutton.cpp
|
||||
continuouspanel.cpp accessibletoolbutton.cpp scoreaccessibility.cpp
|
||||
|
||||
${OMR_FILES}
|
||||
${AUDIO}
|
||||
|
|
|
@ -402,10 +402,10 @@ void ScoreView::doDragFoto(QMouseEvent* ev)
|
|||
QRectF rr(_foto->rect());
|
||||
r = _matrix.mapRect(rr);
|
||||
QSize sz(r.size().toSize());
|
||||
mscore->statusBar()->showMessage(QString("%1 x %2").arg(sz.width()).arg(sz.height()), 3000);
|
||||
//mscore->statusBar()->showMessage(QString("%1 x %2").arg(sz.width()).arg(sz.height()), 3000);
|
||||
|
||||
update();
|
||||
mscore->showMessage("drag", 2000);
|
||||
//mscore->showMessage("drag", 2000);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
|
113
mscore/menus.cpp
113
mscore/menus.cpp
|
@ -292,23 +292,10 @@ Palette* MuseScore::newBarLinePalette()
|
|||
sp->setGrid(42, 38);
|
||||
|
||||
// bar line styles
|
||||
struct {
|
||||
BarLineType type;
|
||||
const char* name;
|
||||
} t[] = {
|
||||
{ BarLineType::NORMAL, QT_TRANSLATE_NOOP("Palette", "Normal") },
|
||||
{ BarLineType::BROKEN, QT_TRANSLATE_NOOP("Palette", "Dashed style") },
|
||||
{ BarLineType::DOTTED, QT_TRANSLATE_NOOP("Palette", "Dotted style") },
|
||||
{ BarLineType::END, QT_TRANSLATE_NOOP("Palette", "End Bar style") },
|
||||
{ BarLineType::DOUBLE, QT_TRANSLATE_NOOP("Palette", "Double Bar style") },
|
||||
{ BarLineType::START_REPEAT, QT_TRANSLATE_NOOP("Palette", "Start Repeat") },
|
||||
{ BarLineType::END_REPEAT, QT_TRANSLATE_NOOP("Palette", "End Repeat") },
|
||||
{ BarLineType::END_START_REPEAT, QT_TRANSLATE_NOOP("Palette", "End-Start Repeat") },
|
||||
};
|
||||
for (unsigned i = 0; i < sizeof(t)/sizeof(*t); ++i) {
|
||||
for (unsigned i = 0; i < barLineTableSize(); ++i) {
|
||||
BarLine* b = new BarLine(gscore);
|
||||
b->setBarLineType(t[i].type);
|
||||
sp->append(b, t[i].name);
|
||||
b->setBarLineType(barLineTable[i].type);
|
||||
sp->append(b, barLineTable[i].name);
|
||||
}
|
||||
|
||||
// bar line spans
|
||||
|
@ -346,57 +333,21 @@ Palette* MuseScore::newRepeatsPalette()
|
|||
RepeatMeasure* rm = new RepeatMeasure(gscore);
|
||||
sp->append(rm, tr("Repeat measure sign"));
|
||||
|
||||
Marker* mk = new Marker(gscore);
|
||||
mk->setMarkerType(Marker::Type::SEGNO);
|
||||
sp->append(mk, tr("Segno"));
|
||||
for (int i = 0; i < markerTypeTableSize(); i++) {
|
||||
if(markerTypeTable[i].type == Marker::Type::CODETTA) //not in smufl
|
||||
continue;
|
||||
|
||||
mk = new Marker(gscore);
|
||||
mk->setMarkerType(Marker::Type::VARSEGNO);
|
||||
sp->append(mk, tr("Segno Variation"));
|
||||
Marker* mk = new Marker(gscore);
|
||||
mk->setMarkerType(markerTypeTable[i].type);
|
||||
sp->append(mk, markerTypeTable[i].name);
|
||||
}
|
||||
|
||||
mk = new Marker(gscore);
|
||||
mk->setMarkerType(Marker::Type::CODA);
|
||||
sp->append(mk, tr("Coda"));
|
||||
for (int i = 0; i < jumpTypeTableSize(); i++) {
|
||||
Jump* jp = new Jump(gscore);
|
||||
jp->setJumpType(jumpTypeTable[i].type);
|
||||
sp->append(jp, jumpTypeTable[i].userText);
|
||||
}
|
||||
|
||||
mk = new Marker(gscore);
|
||||
mk->setMarkerType(Marker::Type::VARCODA);
|
||||
sp->append(mk, tr("Varied coda"));
|
||||
|
||||
/* mk = new Marker(gscore); // not in smufl
|
||||
mk->setMarkerType(Marker::Type::CODETTA);
|
||||
sp->append(mk, tr("Codetta"));
|
||||
*/
|
||||
mk = new Marker(gscore);
|
||||
mk->setMarkerType(Marker::Type::FINE);
|
||||
sp->append(mk, tr("Fine"));
|
||||
|
||||
Jump* jp = new Jump(gscore);
|
||||
jp->setJumpType(Jump::Type::DC);
|
||||
sp->append(jp, tr("Da Capo"));
|
||||
|
||||
jp = new Jump(gscore);
|
||||
jp->setJumpType(Jump::Type::DC_AL_FINE);
|
||||
sp->append(jp, tr("Da Capo al Fine"));
|
||||
|
||||
jp = new Jump(gscore);
|
||||
jp->setJumpType(Jump::Type::DC_AL_CODA);
|
||||
sp->append(jp, tr("Da Capo al Coda"));
|
||||
|
||||
jp = new Jump(gscore);
|
||||
jp->setJumpType(Jump::Type::DS_AL_CODA);
|
||||
sp->append(jp, tr("D.S. al Coda"));
|
||||
|
||||
jp = new Jump(gscore);
|
||||
jp->setJumpType(Jump::Type::DS_AL_FINE);
|
||||
sp->append(jp, tr("D.S. al Fine"));
|
||||
|
||||
jp = new Jump(gscore);
|
||||
jp->setJumpType(Jump::Type::DS);
|
||||
sp->append(jp, tr("D.S."));
|
||||
|
||||
mk = new Marker(gscore);
|
||||
mk->setMarkerType(Marker::Type::TOCODA);
|
||||
sp->append(mk, tr("To Coda"));
|
||||
return sp;
|
||||
}
|
||||
|
||||
|
@ -629,12 +580,6 @@ Palette* MuseScore::newArpeggioPalette()
|
|||
}
|
||||
|
||||
//fall and doits
|
||||
const char* scorelineNames[] = {
|
||||
QT_TR_NOOP("fall"),
|
||||
QT_TR_NOOP("doit"),
|
||||
QT_TR_NOOP("plop"),
|
||||
QT_TR_NOOP("scoop"),
|
||||
};
|
||||
|
||||
ChordLine* cl = new ChordLine(gscore);
|
||||
cl->setChordLineType(ChordLineType::FALL);
|
||||
|
@ -879,29 +824,13 @@ Palette* MuseScore::newLinesPalette()
|
|||
pedal->setEndHook(true);
|
||||
sp->append(pedal, QT_TRANSLATE_NOOP("Palette", "Pedal"));
|
||||
|
||||
Trill* trill = new Trill(gscore);
|
||||
trill->setLen(w);
|
||||
sp->append(trill, QT_TRANSLATE_NOOP("Palette", "Trill line"));
|
||||
|
||||
trill = new Trill(gscore);
|
||||
trill->setTrillType("upprall");
|
||||
trill->setLen(w);
|
||||
sp->append(trill, QT_TRANSLATE_NOOP("Palette", "Upprall line"));
|
||||
|
||||
trill = new Trill(gscore);
|
||||
trill->setTrillType("downprall");
|
||||
trill->setLen(w);
|
||||
sp->append(trill, QT_TRANSLATE_NOOP("Palette", "Downprall line"));
|
||||
|
||||
trill = new Trill(gscore);
|
||||
trill->setTrillType("prallprall");
|
||||
trill->setLen(w);
|
||||
sp->append(trill, QT_TRANSLATE_NOOP("Palette", "Prallprall line"));
|
||||
|
||||
trill = new Trill(gscore);
|
||||
trill->setTrillType("pure");
|
||||
trill->setLen(w);
|
||||
sp->append(trill, QT_TRANSLATE_NOOP("Palette", "Wavy line"));
|
||||
for (int i = 0; i < trillTableSize(); i++) {
|
||||
Trill* trill = new Trill(gscore);
|
||||
trill->setTrillType(trillTable[i].type);
|
||||
trill->setLen(w);
|
||||
sp->append(trill, trillTable[i].userName);
|
||||
}
|
||||
|
||||
TextLine* textLine = new TextLine(gscore);
|
||||
textLine->setLen(w);
|
||||
|
|
|
@ -79,6 +79,7 @@
|
|||
#include "texttools.h"
|
||||
#include "textpalette.h"
|
||||
#include "resourceManager.h"
|
||||
#include "scoreaccessibility.h"
|
||||
|
||||
#include "libmscore/mscore.h"
|
||||
#include "libmscore/system.h"
|
||||
|
@ -462,7 +463,9 @@ MuseScore::MuseScore()
|
|||
_modeText = new QLabel;
|
||||
_modeText->setAutoFillBackground(false);
|
||||
_modeText->setObjectName("modeLabel");
|
||||
|
||||
_statusBar = new QStatusBar;
|
||||
|
||||
hRasterAction = getAction("hraster");
|
||||
hRasterAction->setCheckable(true);
|
||||
vRasterAction = getAction("vraster");
|
||||
|
@ -508,6 +511,7 @@ MuseScore::MuseScore()
|
|||
_statusBar->addPermanentWidget(_positionLabel, 0);
|
||||
|
||||
setStatusBar(_statusBar);
|
||||
ScoreAccessibility::createInstance(this);
|
||||
|
||||
_progressBar = 0;
|
||||
|
||||
|
@ -1613,9 +1617,10 @@ void MuseScore::setCurrentScoreView(ScoreView* view)
|
|||
a->setChecked(cs->styleB(StyleIdx::concertPitch));
|
||||
|
||||
setPos(cs->inputPos());
|
||||
showMessage(cs->filePath(), 2000);
|
||||
//showMessage(cs->filePath(), 2000);
|
||||
if (_navigator && _navigator->widget())
|
||||
navigator()->setScoreView(view);
|
||||
ScoreAccessibility::instance()->updateAccessibilityInfo();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
@ -2413,7 +2418,7 @@ bool MuseScoreApplication::event(QEvent *event)
|
|||
paths.append(static_cast<QFileOpenEvent *>(event)->file());
|
||||
return true;
|
||||
default:
|
||||
return QApplication::event(event);
|
||||
return QtSingleApplication::event(event);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2431,7 +2436,7 @@ bool MuseScore::eventFilter(QObject *obj, QEvent *event)
|
|||
handleMessage(static_cast<QFileOpenEvent *>(event)->file());
|
||||
return true;
|
||||
default:
|
||||
return QObject::eventFilter(obj, event);
|
||||
return QMainWindow::eventFilter(obj, event);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2779,7 +2784,9 @@ void MuseScore::readSettings()
|
|||
mainWindow->setOpaqueResize(false);
|
||||
|
||||
move(settings.value("pos", QPoint(10, 10)).toPoint());
|
||||
if (settings.value("maximized", false).toBool())
|
||||
//for some reason when MuseScore starts maximized the screen-reader
|
||||
//doesn't respond to QAccessibleEvents
|
||||
if (settings.value("maximized", false).toBool() && !QAccessible::isActive())
|
||||
showMaximized();
|
||||
mscore->showPalette(settings.value("showPanel", "1").toBool());
|
||||
mscore->showInspector(settings.value("showInspector", "0").toBool());
|
||||
|
@ -4003,6 +4010,7 @@ void MuseScore::endCmd()
|
|||
if (e == 0 && cs->noteEntryMode())
|
||||
e = cs->inputState().cr();
|
||||
cs->end();
|
||||
ScoreAccessibility::instance()->updateAccessibilityInfo();
|
||||
}
|
||||
else {
|
||||
if (inspector)
|
||||
|
@ -4553,6 +4561,8 @@ namespace Ms {
|
|||
|
||||
using namespace Ms;
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------
|
||||
// main
|
||||
//---------------------------------------------------------
|
||||
|
@ -4577,6 +4587,7 @@ int main(int argc, char* av[])
|
|||
QCoreApplication::setOrganizationName("MuseScore");
|
||||
QCoreApplication::setOrganizationDomain("musescore.org");
|
||||
QCoreApplication::setApplicationName("MuseScoreDevelopment");
|
||||
QAccessible::installFactory(AccessibleScoreView::ScoreViewFactory);
|
||||
Q_INIT_RESOURCE(zita);
|
||||
Q_INIT_RESOURCE(noeffect);
|
||||
// Q_INIT_RESOURCE(freeverb);
|
||||
|
@ -5021,6 +5032,7 @@ int main(int argc, char* av[])
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return qApp->exec();
|
||||
}
|
||||
|
||||
|
|
206
mscore/scoreaccessibility.cpp
Normal file
206
mscore/scoreaccessibility.cpp
Normal file
|
@ -0,0 +1,206 @@
|
|||
#include <QMainWindow>
|
||||
#include <QWidget>
|
||||
#include "scoreaccessibility.h"
|
||||
#include "musescore.h"
|
||||
#include "libmscore/segment.h"
|
||||
#include "libmscore/timesig.h"
|
||||
#include "libmscore/score.h"
|
||||
#include "libmscore/measure.h"
|
||||
#include "inspector/inspector.h"
|
||||
|
||||
namespace Ms{
|
||||
AccessibleScoreView::AccessibleScoreView(ScoreView* scView) : QAccessibleWidget(scView){
|
||||
s = scView;
|
||||
}
|
||||
|
||||
int AccessibleScoreView::childCount() const{
|
||||
return 0;
|
||||
}
|
||||
|
||||
QAccessibleInterface* AccessibleScoreView::child(int /*index*/) const{
|
||||
return 0;
|
||||
}
|
||||
QAccessibleInterface* AccessibleScoreView::parent() const{
|
||||
return QAccessibleWidget::parent();
|
||||
}
|
||||
QRect AccessibleScoreView::rect() const{
|
||||
return s->rect();
|
||||
}
|
||||
QAccessible::Role AccessibleScoreView::role() const{
|
||||
return QAccessible::NoRole;
|
||||
}
|
||||
|
||||
QString AccessibleScoreView::text(QAccessible::Text t) const {
|
||||
switch (t) {
|
||||
case QAccessible::Name:
|
||||
return tr("Score %1").arg(s->score()->name());
|
||||
case QAccessible::Value:
|
||||
return s->score()->accessibleInfo();
|
||||
default:
|
||||
return QString();
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
QWindow* AccessibleScoreView::window() const {
|
||||
return qApp->focusWindow();
|
||||
}
|
||||
|
||||
QAccessibleInterface* AccessibleScoreView::ScoreViewFactory(const QString &classname, QObject *object)
|
||||
{
|
||||
QAccessibleInterface *iface = 0;
|
||||
if (classname == QLatin1String("Ms::ScoreView") && object && object->isWidgetType()){
|
||||
qDebug("Creating interface for ScoreView object");
|
||||
iface = static_cast<QAccessibleInterface*>(new AccessibleScoreView(static_cast<ScoreView*>(object)));
|
||||
}
|
||||
|
||||
return iface;
|
||||
}
|
||||
|
||||
|
||||
ScoreAccessibility* ScoreAccessibility::inst = 0;
|
||||
|
||||
ScoreAccessibility::ScoreAccessibility(QMainWindow* mainWindow) : QObject(mainWindow)
|
||||
{
|
||||
this->mainWindow = mainWindow;
|
||||
statusBarLabel = 0;
|
||||
}
|
||||
|
||||
void ScoreAccessibility::createInstance(QMainWindow* mainWindow)
|
||||
{
|
||||
if (!inst) {
|
||||
inst = new ScoreAccessibility(mainWindow);
|
||||
}
|
||||
}
|
||||
|
||||
ScoreAccessibility::~ScoreAccessibility()
|
||||
{
|
||||
}
|
||||
|
||||
void ScoreAccessibility::clearAccessibilityInfo()
|
||||
{
|
||||
if(statusBarLabel != 0) {
|
||||
mainWindow->statusBar()->removeWidget(statusBarLabel);
|
||||
delete statusBarLabel;
|
||||
statusBarLabel = 0;
|
||||
static_cast<MuseScore*>(mainWindow)->currentScoreView()->score()->setAccessibleInfo(tr("No selection"));
|
||||
}
|
||||
}
|
||||
|
||||
void ScoreAccessibility::currentInfoChanged()
|
||||
{
|
||||
clearAccessibilityInfo();
|
||||
statusBarLabel = new QLabel(mainWindow->statusBar());
|
||||
ScoreView* scoreView = static_cast<MuseScore*>(mainWindow)->currentScoreView();
|
||||
Score* score = scoreView->score();
|
||||
if (score->selection().isSingle()) {
|
||||
Element* e = score->selection().element();
|
||||
if (!e) {
|
||||
return;
|
||||
}
|
||||
Element* el = e->isSpannerSegment() ? static_cast<SpannerSegment*>(e)->spanner() : e;
|
||||
QString barsAndBeats = "";
|
||||
std::pair<int, float> bar_beat;
|
||||
if (el->isSpanner()){
|
||||
Spanner* s = static_cast<Spanner*>(el);
|
||||
bar_beat = barbeat(s->startSegment());
|
||||
barsAndBeats += tr("Start Bar: %1").arg(QString::number(bar_beat.first)) + " " + tr("Start Beat: %1").arg(QString::number(bar_beat.second));
|
||||
Segment* seg = s->endSegment();
|
||||
if(!seg)
|
||||
seg = score->lastSegment()->prev1MM(Segment::Type::ChordRest);
|
||||
|
||||
if (seg->tick() != score->lastSegment()->prev1MM(Segment::Type::ChordRest)->tick() &&
|
||||
s->type() != Element::Type::SLUR &&
|
||||
s->type() != Element::Type::TIE )
|
||||
seg = seg->prev1MM(Segment::Type::ChordRest);
|
||||
|
||||
bar_beat = barbeat(seg);
|
||||
barsAndBeats += " " + tr("End Bar: %1").arg(QString::number(bar_beat.first)) + " " + tr("End Beat: %1").arg(QString::number(bar_beat.second));
|
||||
}
|
||||
else {
|
||||
std::pair<int, float>bar_beat = barbeat(el);
|
||||
if (bar_beat.first) {
|
||||
barsAndBeats += " " + tr("Bar: %1").arg(QString::number(bar_beat.first));
|
||||
if (bar_beat.second)
|
||||
barsAndBeats += " " + tr("Beat: %1").arg(QString::number(bar_beat.second));
|
||||
}
|
||||
}
|
||||
|
||||
statusBarLabel->setText(e->accessibleInfo() + barsAndBeats);
|
||||
score->setAccessibleInfo(e->screenReaderInfo() + barsAndBeats + " " + e->accessibleExtraInfo());
|
||||
}
|
||||
else if (score->selection().isRange()) {
|
||||
QString barsAndBeats = "";
|
||||
std::pair<int, float> bar_beat;
|
||||
|
||||
bar_beat = barbeat(score->selection().startSegment());
|
||||
barsAndBeats += " " + tr("Start Bar: %1").arg(QString::number(bar_beat.first)) + " " + tr("Start Beat: %1").arg(QString::number(bar_beat.second));
|
||||
Segment* endSegment = score->selection().endSegment();
|
||||
|
||||
if (!endSegment)
|
||||
endSegment = score->lastSegment();
|
||||
else
|
||||
endSegment = endSegment->prev1MM();
|
||||
|
||||
bar_beat = barbeat(endSegment);
|
||||
barsAndBeats += " " + tr("End Bar: %1").arg(QString::number(bar_beat.first)) + " " + tr("End Beat: %1").arg(QString::number(bar_beat.second));
|
||||
statusBarLabel->setText(tr("Range Selection") + barsAndBeats);
|
||||
score->setAccessibleInfo(tr("Range Selection") + barsAndBeats);
|
||||
}
|
||||
else if (score->selection().isList()) {
|
||||
statusBarLabel->setText(tr("List Selection"));
|
||||
score->setAccessibleInfo(tr("List Selection"));
|
||||
}
|
||||
mainWindow->statusBar()->addWidget(statusBarLabel);
|
||||
}
|
||||
|
||||
ScoreAccessibility* ScoreAccessibility::instance()
|
||||
{
|
||||
return inst;
|
||||
}
|
||||
|
||||
void ScoreAccessibility::updateAccessibilityInfo()
|
||||
{
|
||||
currentInfoChanged();
|
||||
ScoreView* w = static_cast<MuseScore*>(mainWindow)->currentScoreView();
|
||||
|
||||
//getInspector->isAncestorOf is used so that inspector doesn't lose focus
|
||||
//when this method is called
|
||||
if ( (qApp->focusWidget() != w) && !mscore->getInspector()->isAncestorOf(qApp->focusWidget())) {
|
||||
w->setFocus();
|
||||
}
|
||||
QObject* obj = static_cast<QObject*>(w);
|
||||
QAccessibleValueChangeEvent ev(obj, w->score()->accessibleInfo());
|
||||
QAccessible::updateAccessibility(&ev);
|
||||
}
|
||||
|
||||
std::pair<int, float> ScoreAccessibility::barbeat(Element *e)
|
||||
{
|
||||
if (!e) {
|
||||
return std::pair<int, float>(0, 0);
|
||||
}
|
||||
|
||||
int bar;
|
||||
int beat;
|
||||
int ticks;
|
||||
TimeSigMap* tsm = e->score()->sigmap();
|
||||
Element* p = e;
|
||||
while(p && p->type() != Element::Type::SEGMENT && p->type() != Element::Type::MEASURE)
|
||||
p = p->parent();
|
||||
|
||||
if (!p) {
|
||||
return std::pair<int, float>(0, 0);
|
||||
}
|
||||
else if (p->type() == Element::Type::SEGMENT) {
|
||||
Segment* seg = static_cast<Segment*>(p);
|
||||
tsm->tickValues(seg->tick(), &bar, &beat, &ticks);
|
||||
}
|
||||
else if (p->type() == Element::Type::MEASURE) {
|
||||
Measure* m = static_cast<Measure*>(p);
|
||||
bar = m->no();
|
||||
beat = -1;
|
||||
ticks = 0;
|
||||
}
|
||||
return pair<int,float>(bar + 1, beat + 1 + ticks / static_cast<float>(MScore::division));
|
||||
}
|
||||
}
|
45
mscore/scoreaccessibility.h
Normal file
45
mscore/scoreaccessibility.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
#ifndef __SCORE_ACCESSIBILITY__
|
||||
#define __SCORE_ACCESSIBILITY__
|
||||
|
||||
#include<QStatusBar>
|
||||
#include<QAccessible>
|
||||
#include<QAccessibleWidget>
|
||||
#include "scoreview.h"
|
||||
|
||||
namespace Ms {
|
||||
class AccessibleScoreView : public QAccessibleWidget {
|
||||
public:
|
||||
AccessibleScoreView(ScoreView* c);
|
||||
int childCount() const Q_DECL_OVERRIDE;
|
||||
QAccessibleInterface* child(int /*index*/) const Q_DECL_OVERRIDE;
|
||||
QAccessibleInterface* parent() const Q_DECL_OVERRIDE;
|
||||
QRect rect() const Q_DECL_OVERRIDE;
|
||||
QAccessible::Role role() const Q_DECL_OVERRIDE;
|
||||
QString text(QAccessible::Text t) const Q_DECL_OVERRIDE;
|
||||
QWindow* window() const Q_DECL_OVERRIDE;
|
||||
static QAccessibleInterface* ScoreViewFactory(const QString &classname, QObject *object);
|
||||
private:
|
||||
ScoreView* s;
|
||||
};
|
||||
|
||||
class ScoreAccessibility : public QObject {
|
||||
Q_OBJECT
|
||||
private:
|
||||
static ScoreAccessibility* inst;
|
||||
QMainWindow* mainWindow;
|
||||
QLabel* statusBarLabel;
|
||||
ScoreAccessibility(QMainWindow* statusBar);
|
||||
std::pair<int, float>barbeat(Element* e);
|
||||
|
||||
public:
|
||||
~ScoreAccessibility();
|
||||
void updateAccessibilityInfo();
|
||||
void clearAccessibilityInfo();
|
||||
static void createInstance(QMainWindow* statusBar);
|
||||
static ScoreAccessibility* instance();
|
||||
void currentInfoChanged();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -2482,8 +2482,9 @@ void ScoreView::cmd(const QAction* a)
|
|||
if (MScore::debugMode)
|
||||
qDebug("ScoreView::cmd <%s>", qPrintable(cmd));
|
||||
|
||||
if (cmd == "escape")
|
||||
if (cmd == "escape") {
|
||||
sm->postEvent(new CommandEvent(cmd));
|
||||
}
|
||||
else if (cmd == "note-input" || cmd == "copy" || cmd == "paste"
|
||||
|| cmd == "cut" || cmd == "fotomode") {
|
||||
sm->postEvent(new CommandEvent(cmd));
|
||||
|
|
Loading…
Reference in a new issue