Merge pull request #3862 from dmitrio95/scorecmp_tool
GSoC 2018: Score comparison tool
This commit is contained in:
commit
e32ff8e44a
110 changed files with 4006 additions and 452 deletions
1
all.h
1
all.h
|
@ -218,6 +218,7 @@
|
|||
// Undefined problematic #def'd macros in Microsoft headers
|
||||
#undef STRING_NONE
|
||||
#undef small
|
||||
#undef DELETE
|
||||
#endif
|
||||
|
||||
#endif // __cplusplus
|
||||
|
|
|
@ -38,6 +38,10 @@ else (NOT MSVC)
|
|||
set(_all_h_file "${PROJECT_SOURCE_DIR}/all.h")
|
||||
endif (NOT MSVC)
|
||||
|
||||
include_directories(
|
||||
${PROJECT_SOURCE_DIR}/thirdparty/diff
|
||||
)
|
||||
|
||||
add_library (
|
||||
libmscore STATIC
|
||||
${_all_h_file}
|
||||
|
@ -99,6 +103,11 @@ add_library (
|
|||
lyricsline.cpp
|
||||
layoutlinear.cpp
|
||||
connector.cpp location.cpp skyline.cpp
|
||||
scorediff.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(libmscore
|
||||
diff_match_patch
|
||||
)
|
||||
|
||||
##
|
||||
|
|
|
@ -187,7 +187,7 @@ void Accidental::read(XmlReader& e)
|
|||
|
||||
void Accidental::write(XmlWriter& xml) const
|
||||
{
|
||||
xml.stag(name());
|
||||
xml.stag(this);
|
||||
writeProperty(xml, Pid::ACCIDENTAL_BRACKET);
|
||||
writeProperty(xml, Pid::ROLE);
|
||||
writeProperty(xml, Pid::SMALL);
|
||||
|
@ -440,6 +440,20 @@ bool Accidental::setProperty(Pid propertyId, const QVariant& v)
|
|||
return true;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// propertyUserValue
|
||||
//---------------------------------------------------------
|
||||
|
||||
QString Accidental::propertyUserValue(Pid pid) const
|
||||
{
|
||||
switch(pid) {
|
||||
case Pid::SUBTYPE:
|
||||
return subtypeUserName();
|
||||
default:
|
||||
return Element::propertyUserValue(pid);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// accessibleInfo
|
||||
//---------------------------------------------------------
|
||||
|
|
|
@ -211,6 +211,7 @@ class Accidental final : public Element {
|
|||
virtual QVariant getProperty(Pid propertyId) const override;
|
||||
virtual bool setProperty(Pid propertyId, const QVariant&) override;
|
||||
virtual QVariant propertyDefault(Pid propertyId) const override;
|
||||
virtual QString propertyUserValue(Pid) const;
|
||||
|
||||
static AccidentalVal subtype2value(AccidentalType); // return effective pitch offset
|
||||
static const char* subtype2name(AccidentalType);
|
||||
|
|
|
@ -182,7 +182,7 @@ void Ambitus::setBottomTpc(int val)
|
|||
|
||||
void Ambitus::write(XmlWriter& xml) const
|
||||
{
|
||||
xml.stag("Ambitus");
|
||||
xml.stag(this);
|
||||
xml.tag(Pid::HEAD_GROUP, int(_noteHeadGroup), int(NOTEHEADGROUP_DEFAULT));
|
||||
xml.tag(Pid::HEAD_TYPE, int(_noteHeadType), int(NOTEHEADTYPE_DEFAULT));
|
||||
xml.tag(Pid::MIRROR_HEAD,int(_dir), int(DIR_DEFAULT));
|
||||
|
|
|
@ -56,7 +56,7 @@ void Arpeggio::write(XmlWriter& xml) const
|
|||
{
|
||||
if (!xml.canWrite(this))
|
||||
return;
|
||||
xml.stag("Arpeggio");
|
||||
xml.stag(this);
|
||||
Element::writeProperties(xml);
|
||||
xml.tag("subtype", int(_arpeggioType));
|
||||
if (_userLen1 != 0.0)
|
||||
|
|
|
@ -143,7 +143,7 @@ void Articulation::write(XmlWriter& xml) const
|
|||
{
|
||||
if (!xml.canWrite(this))
|
||||
return;
|
||||
xml.stag("Articulation");
|
||||
xml.stag(this);
|
||||
if (!_channelName.isEmpty())
|
||||
xml.tagE(QString("channel name=\"%1\"").arg(_channelName));
|
||||
writeProperty(xml, Pid::DIRECTION);
|
||||
|
|
|
@ -357,7 +357,7 @@ noteList BagpipeEmbellishment::getNoteList() const
|
|||
|
||||
void BagpipeEmbellishment::write(XmlWriter& xml) const
|
||||
{
|
||||
xml.stag(name());
|
||||
xml.stag(this);
|
||||
xml.tag("subtype", _embelType);
|
||||
xml.etag();
|
||||
}
|
||||
|
|
|
@ -505,7 +505,7 @@ void BarLine::drawEditMode(QPainter* p, EditData& ed)
|
|||
|
||||
void BarLine::write(XmlWriter& xml) const
|
||||
{
|
||||
xml.stag("BarLine");
|
||||
xml.stag(this);
|
||||
|
||||
writeProperty(xml, Pid::BARLINE_TYPE);
|
||||
writeProperty(xml, Pid::BARLINE_SPAN);
|
||||
|
|
|
@ -1989,7 +1989,7 @@ void Beam::write(XmlWriter& xml) const
|
|||
{
|
||||
if (_elements.empty())
|
||||
return;
|
||||
xml.stag(name());
|
||||
xml.stag(this);
|
||||
Element::writeProperties(xml);
|
||||
|
||||
writeProperty(xml, Pid::STEM_DIRECTION);
|
||||
|
|
|
@ -280,7 +280,7 @@ void Bend::draw(QPainter* painter) const
|
|||
|
||||
void Bend::write(XmlWriter& xml) const
|
||||
{
|
||||
xml.stag("Bend");
|
||||
xml.stag(this);
|
||||
for (const PitchValue& v : _points) {
|
||||
xml.tagE(QString("point time=\"%1\" pitch=\"%2\" vibrato=\"%3\"")
|
||||
.arg(v.time).arg(v.pitch).arg(v.vibrato));
|
||||
|
|
|
@ -189,7 +189,7 @@ void Box::updateGrips(EditData& ed) const
|
|||
|
||||
void Box::write(XmlWriter& xml) const
|
||||
{
|
||||
xml.stag(name());
|
||||
xml.stag(this);
|
||||
writeProperties(xml);
|
||||
xml.etag();
|
||||
}
|
||||
|
|
|
@ -446,16 +446,16 @@ void Bracket::write(XmlWriter& xml) const
|
|||
{
|
||||
switch (_bi->bracketType()) {
|
||||
case BracketType::BRACE:
|
||||
xml.stag("Bracket type=\"Brace\"");
|
||||
xml.stag(this, "type=\"Brace\"");
|
||||
break;
|
||||
case BracketType::NORMAL:
|
||||
xml.stag("Bracket");
|
||||
xml.stag(this);
|
||||
break;
|
||||
case BracketType::SQUARE:
|
||||
xml.stag("Bracket type=\"Square\"");
|
||||
xml.stag(this, "type=\"Square\"");
|
||||
break;
|
||||
case BracketType::LINE:
|
||||
xml.stag("Bracket type=\"Line\"");
|
||||
xml.stag(this, "type=\"Line\"");
|
||||
break;
|
||||
case BracketType::NO_BRACKET:
|
||||
break;
|
||||
|
|
|
@ -76,7 +76,7 @@ void Breath::write(XmlWriter& xml) const
|
|||
{
|
||||
if (!xml.canWrite(this))
|
||||
return;
|
||||
xml.stag("Breath");
|
||||
xml.stag(this);
|
||||
writeProperty(xml, Pid::SYMBOL);
|
||||
writeProperty(xml, Pid::PAUSE);
|
||||
Element::writeProperties(xml);
|
||||
|
|
|
@ -908,7 +908,7 @@ void Chord::write(XmlWriter& xml) const
|
|||
c->write(xml);
|
||||
}
|
||||
writeBeam(xml);
|
||||
xml.stag("Chord");
|
||||
xml.stag(this);
|
||||
ChordRest::writeProperties(xml);
|
||||
for (const Articulation* a : _articulations)
|
||||
a->write(xml);
|
||||
|
|
|
@ -207,7 +207,7 @@ void ChordLine::read(XmlReader& e)
|
|||
|
||||
void ChordLine::write(XmlWriter& xml) const
|
||||
{
|
||||
xml.stag(name());
|
||||
xml.stag(this);
|
||||
xml.tag("subtype", int(_chordLineType));
|
||||
xml.tag("straight", _straight, false);
|
||||
xml.tag("lengthX", _lengthX, 0.0);
|
||||
|
|
|
@ -310,7 +310,7 @@ void Clef::read(XmlReader& e)
|
|||
|
||||
void Clef::write(XmlWriter& xml) const
|
||||
{
|
||||
xml.stag(name());
|
||||
xml.stag(this);
|
||||
if (_clefTypes._concertClef != ClefType::INVALID)
|
||||
xml.tag("concertClefType", ClefInfo::tag(_clefTypes._concertClef));
|
||||
if (_clefTypes._transposingClef != ClefType::INVALID)
|
||||
|
|
|
@ -147,6 +147,8 @@ void Score::startCmd()
|
|||
|
||||
void Score::undoRedo(bool undo, EditData* ed)
|
||||
{
|
||||
if (readOnly())
|
||||
return;
|
||||
deselectAll();
|
||||
cmdState().reset();
|
||||
if (undo)
|
||||
|
@ -170,7 +172,7 @@ void Score::endCmd(bool rollback)
|
|||
update();
|
||||
return;
|
||||
}
|
||||
if (MScore::_error != MS_NO_ERROR)
|
||||
if (readOnly() || MScore::_error != MS_NO_ERROR)
|
||||
rollback = true;
|
||||
|
||||
if (rollback)
|
||||
|
|
|
@ -49,7 +49,7 @@ QVariant ElementW::get(const QString& s) const
|
|||
{
|
||||
QVariant val;
|
||||
if (e) {
|
||||
Pid pid = propertyId(s);
|
||||
Pid pid = propertyIdQml(s);
|
||||
val = e->getProperty(pid);
|
||||
if (propertyType(pid) == P_TYPE::FRACTION) {
|
||||
Fraction f(val.value<Fraction>());
|
||||
|
|
|
@ -122,7 +122,7 @@ void Dynamic::write(XmlWriter& xml) const
|
|||
{
|
||||
if (!xml.canWrite(this))
|
||||
return;
|
||||
xml.stag("Dynamic");
|
||||
xml.stag(this);
|
||||
xml.tag("subtype", dynamicTypeName());
|
||||
writeProperty(xml, Pid::VELOCITY);
|
||||
writeProperty(xml, Pid::DYNAMIC_RANGE);
|
||||
|
|
|
@ -507,13 +507,15 @@ void Element::writeProperties(XmlWriter& xml) const
|
|||
xml.etag(); // </linked>
|
||||
}
|
||||
}
|
||||
if ((track() != xml.curTrack()) && (track() != -1) && !isBeam()) {
|
||||
if ((xml.writeTrack() || track() != xml.curTrack())
|
||||
&& (track() != -1) && !isBeam()) {
|
||||
// Writing track number for beams is redundant as it is calculated
|
||||
// during layout.
|
||||
int t;
|
||||
t = track() + xml.trackDiff();
|
||||
int t = track() + xml.trackDiff();
|
||||
xml.tag("track", t);
|
||||
}
|
||||
if (xml.writePosition())
|
||||
xml.tag(Pid::POSITION, rfrac());
|
||||
if (_tag != 0x1) {
|
||||
for (int i = 1; i < MAX_TAGS; i++) {
|
||||
if (_tag == ((unsigned)1 << i)) {
|
||||
|
@ -668,7 +670,7 @@ bool Element::readProperties(XmlReader& e)
|
|||
|
||||
void Element::write(XmlWriter& xml) const
|
||||
{
|
||||
xml.stag(name());
|
||||
xml.stag(this);
|
||||
writeProperties(xml);
|
||||
xml.etag();
|
||||
}
|
||||
|
@ -1066,6 +1068,10 @@ QVariant Element::getProperty(Pid propertyId) const
|
|||
switch (propertyId) {
|
||||
case Pid::TRACK:
|
||||
return track();
|
||||
case Pid::VOICE:
|
||||
return voice();
|
||||
case Pid::POSITION:
|
||||
return rfrac();
|
||||
case Pid::GENERATED:
|
||||
return generated();
|
||||
case Pid::COLOR:
|
||||
|
@ -1101,6 +1107,9 @@ bool Element::setProperty(Pid propertyId, const QVariant& v)
|
|||
case Pid::TRACK:
|
||||
setTrack(v.toInt());
|
||||
break;
|
||||
case Pid::VOICE:
|
||||
setVoice(v.toInt());
|
||||
break;
|
||||
case Pid::GENERATED:
|
||||
setGenerated(v.toBool());
|
||||
break;
|
||||
|
@ -1172,6 +1181,31 @@ QVariant Element::propertyDefault(Pid pid) const
|
|||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// propertyId
|
||||
//---------------------------------------------------------
|
||||
|
||||
Pid Element::propertyId(const QStringRef& name) const
|
||||
{
|
||||
if (name == "pos" || name == "offset")
|
||||
return Pid::OFFSET;
|
||||
return ScoreElement::propertyId(name);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// propertyUserValue
|
||||
//---------------------------------------------------------
|
||||
|
||||
QString Element::propertyUserValue(Pid pid) const
|
||||
{
|
||||
switch(pid) {
|
||||
case Pid::SUBTYPE:
|
||||
return subtypeName();
|
||||
default:
|
||||
return ScoreElement::propertyUserValue(pid);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// custom
|
||||
// check if property is != default
|
||||
|
|
|
@ -179,6 +179,8 @@ class Element : public ScoreElement {
|
|||
MeasureBase* findMeasureBase();
|
||||
const MeasureBase* findMeasureBase() const;
|
||||
|
||||
virtual bool isElement() const override { return true; }
|
||||
|
||||
qreal spatium() const;
|
||||
|
||||
inline void setFlag(ElementFlag f, bool v) { if (v) _flags |= f; else _flags &= ~ElementFlags(f); }
|
||||
|
@ -407,6 +409,8 @@ class Element : public ScoreElement {
|
|||
virtual QVariant getProperty(Pid) const override;
|
||||
virtual bool setProperty(Pid, const QVariant&) override;
|
||||
virtual QVariant propertyDefault(Pid) const override;
|
||||
virtual Pid propertyId(const QStringRef& xmlName) const override;
|
||||
virtual QString propertyUserValue(Pid) const override;
|
||||
virtual Element* propertyDelegate(Pid) { return 0; } // return Spanner for SpannerSegment for some properties
|
||||
|
||||
bool custom(Pid) const;
|
||||
|
|
|
@ -105,7 +105,7 @@ void Fermata::write(XmlWriter& xml) const
|
|||
qDebug("%s not written", name());
|
||||
return;
|
||||
}
|
||||
xml.stag("Fermata");
|
||||
xml.stag(this);
|
||||
xml.tag("subtype", Sym::id2name(_symId));
|
||||
writeProperty(xml, Pid::TIME_STRETCH);
|
||||
writeProperty(xml, Pid::PLAY);
|
||||
|
|
|
@ -405,7 +405,7 @@ QString FiguredBassItem::normalizedText() const
|
|||
|
||||
void FiguredBassItem::write(XmlWriter& xml) const
|
||||
{
|
||||
xml.stag("FiguredBassItem");
|
||||
xml.stag("FiguredBassItem", this);
|
||||
xml.tagE(QString("brackets b0=\"%1\" b1=\"%2\" b2=\"%3\" b3=\"%4\" b4=\"%5\"")
|
||||
.arg(int(parenth[0])) .arg(int(parenth[1])) .arg(int(parenth[2])) .arg(int(parenth[3])) .arg(int(parenth[4])) );
|
||||
if (_prefix != Modifier::NONE)
|
||||
|
@ -1016,7 +1016,7 @@ void FiguredBass::write(XmlWriter& xml) const
|
|||
{
|
||||
if (!xml.canWrite(this))
|
||||
return;
|
||||
xml.stag("FiguredBass");
|
||||
xml.stag(this);
|
||||
if(!onNote())
|
||||
xml.tag("onNote", onNote());
|
||||
if (ticks() > 0)
|
||||
|
|
|
@ -75,6 +75,7 @@ class Fraction {
|
|||
bool operator!=(const Fraction&) const;
|
||||
|
||||
QString print() const { return QString("%1/%2").arg(_numerator).arg(_denominator); }
|
||||
QString toString() const { return print(); }
|
||||
operator QVariant() const { return QVariant::fromValue(*this); }
|
||||
};
|
||||
|
||||
|
|
|
@ -394,7 +394,7 @@ void FretDiagram::write(XmlWriter& xml) const
|
|||
{
|
||||
if (!xml.canWrite(this))
|
||||
return;
|
||||
xml.stag("FretDiagram");
|
||||
xml.stag(this);
|
||||
Element::writeProperties(xml);
|
||||
|
||||
writeProperty(xml, Pid::FRET_STRINGS);
|
||||
|
|
|
@ -370,7 +370,7 @@ void Glissando::write(XmlWriter& xml) const
|
|||
{
|
||||
if (!xml.canWrite(this))
|
||||
return;
|
||||
xml.stag(name());
|
||||
xml.stag(this);
|
||||
if (_showText && !_text.isEmpty())
|
||||
xml.tag("text", _text);
|
||||
|
||||
|
|
|
@ -500,7 +500,7 @@ void Hairpin::write(XmlWriter& xml) const
|
|||
{
|
||||
if (!xml.canWrite(this))
|
||||
return;
|
||||
xml.stag(name());
|
||||
xml.stag(this);
|
||||
xml.tag("subtype", int(_hairpinType));
|
||||
writeProperty(xml, Pid::VELO_CHANGE);
|
||||
writeProperty(xml, Pid::HAIRPIN_CIRCLEDTIP);
|
||||
|
|
|
@ -200,7 +200,7 @@ void Harmony::write(XmlWriter& xml) const
|
|||
{
|
||||
if (!xml.canWrite(this))
|
||||
return;
|
||||
xml.stag("Harmony");
|
||||
xml.stag(this);
|
||||
if (_leftParen)
|
||||
xml.tagE("leftParen");
|
||||
if (_rootTpc != Tpc::TPC_INVALID || _baseTpc != Tpc::TPC_INVALID) {
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace Ms {
|
|||
|
||||
void Icon::write(XmlWriter& xml) const
|
||||
{
|
||||
xml.stag(name());
|
||||
xml.stag(this);
|
||||
xml.tag("subtype", int(_iconType));
|
||||
if (!_action.isEmpty())
|
||||
xml.tag("action", _action.data());
|
||||
|
|
|
@ -214,7 +214,7 @@ void Image::write(XmlWriter& xml) const
|
|||
if (relativeFilePath.isEmpty())
|
||||
relativeFilePath = _linkPath;
|
||||
|
||||
xml.stag("Image");
|
||||
xml.stag(this);
|
||||
BSymbol::writeProperties(xml);
|
||||
// keep old "path" tag, for backward compatibility and because it is used elsewhere
|
||||
// (for instance by Box:read(), Measure:read(), Note:read(), ...)
|
||||
|
|
|
@ -73,7 +73,7 @@ void InstrumentChange::setInstrument(const Instrument& i)
|
|||
|
||||
void InstrumentChange::write(XmlWriter& xml) const
|
||||
{
|
||||
xml.stag(name());
|
||||
xml.stag(this);
|
||||
_instrument->write(xml, part());
|
||||
TextBase::writeProperties(xml);
|
||||
xml.etag();
|
||||
|
|
|
@ -131,7 +131,7 @@ void Jump::read(XmlReader& e)
|
|||
|
||||
void Jump::write(XmlWriter& xml) const
|
||||
{
|
||||
xml.stag(name());
|
||||
xml.stag(this);
|
||||
TextBase::writeProperties(xml);
|
||||
xml.tag("jumpTo", _jumpTo);
|
||||
xml.tag("playUntil", _playUntil);
|
||||
|
|
|
@ -329,7 +329,7 @@ void KeySig::setKey(Key key)
|
|||
|
||||
void KeySig::write(XmlWriter& xml) const
|
||||
{
|
||||
xml.stag(name());
|
||||
xml.stag(this);
|
||||
Element::writeProperties(xml);
|
||||
if (_sig.isAtonal()) {
|
||||
xml.tag("custom", 1);
|
||||
|
|
|
@ -48,7 +48,7 @@ LayoutBreak::LayoutBreak(const LayoutBreak& lb)
|
|||
|
||||
void LayoutBreak::write(XmlWriter& xml) const
|
||||
{
|
||||
xml.stag(name());
|
||||
xml.stag(this);
|
||||
Element::writeProperties(xml);
|
||||
|
||||
writeProperty(xml, Pid::LAYOUT_BREAK);
|
||||
|
|
|
@ -87,7 +87,7 @@ void LetRing::write(XmlWriter& xml) const
|
|||
{
|
||||
if (!xml.canWrite(this))
|
||||
return;
|
||||
xml.stag(name());
|
||||
xml.stag(this);
|
||||
|
||||
for (const StyledProperty& spp : *styledProperties()) {
|
||||
if (!isStyled(spp.pid))
|
||||
|
|
|
@ -1040,7 +1040,7 @@ void SLine::writeProperties(XmlWriter& xml) const
|
|||
//
|
||||
qreal _spatium = spatium();
|
||||
for (const SpannerSegment* seg : spannerSegments()) {
|
||||
xml.stag("Segment");
|
||||
xml.stag("Segment", seg);
|
||||
xml.tag("subtype", int(seg->spannerSegmentType()));
|
||||
xml.tag("offset", seg->offset() / _spatium);
|
||||
xml.tag("off2", seg->userOff2() / _spatium);
|
||||
|
@ -1128,7 +1128,7 @@ const QRectF& SLine::bbox() const
|
|||
|
||||
void SLine::write(XmlWriter& xml) const
|
||||
{
|
||||
xml.stag(name());
|
||||
xml.stag(this);
|
||||
SLine::writeProperties(xml);
|
||||
xml.etag();
|
||||
}
|
||||
|
|
|
@ -135,33 +135,12 @@ void Location::fillPositionForElement(const Element* e, bool absfrac)
|
|||
qWarning("Location::fillPositionForElement: element is nullptr");
|
||||
return;
|
||||
}
|
||||
if (track() == absDefaults.track()) {
|
||||
const int track = e->track();
|
||||
setTrack(track);
|
||||
if (track < 0) {
|
||||
const MeasureBase* mb = e->findMeasureBase();
|
||||
if (mb && !mb->isMeasure()) {
|
||||
// Such elements are written in the first staff,
|
||||
// see writeMeasure() in scorefile.cpp
|
||||
setTrack(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (track() == absDefaults.track())
|
||||
setTrack(track(e));
|
||||
if (frac() == absDefaults.frac())
|
||||
setFrac(absfrac ? e->afrac() : e->rfrac());
|
||||
if (measure() == absDefaults.measure()) {
|
||||
if (absfrac)
|
||||
setMeasure(0);
|
||||
else {
|
||||
const Measure* m = toMeasure(e->findMeasure());
|
||||
if (m)
|
||||
setMeasure(m->measureIndex());
|
||||
else {
|
||||
qWarning("Location::fillFor: cannot find element's measure (%s)", e->name());
|
||||
setMeasure(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (measure() == absDefaults.measure())
|
||||
setMeasure(absfrac ? 0 : measure(e));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
@ -180,26 +159,8 @@ void Location::fillForElement(const Element* e, bool absfrac)
|
|||
}
|
||||
|
||||
fillPositionForElement(e, absfrac);
|
||||
|
||||
if (e->isChord() || (e->parent() && e->parent()->isChord())) {
|
||||
const Chord* ch = e->isChord() ? toChord(e) : toChord(e->parent());
|
||||
if (ch->isGrace())
|
||||
setGraceIndex(ch->graceIndex());
|
||||
}
|
||||
if (e->isNote()) {
|
||||
const Note* n = toNote(e);
|
||||
const std::vector<Note*>& notes = n->chord()->notes();
|
||||
if (notes.size() == 1)
|
||||
setNote(0);
|
||||
else {
|
||||
int noteIdx;
|
||||
for (noteIdx = 0; noteIdx < int(notes.size()); ++noteIdx) {
|
||||
if (n == notes.at(noteIdx))
|
||||
break;
|
||||
}
|
||||
setNote(noteIdx);
|
||||
}
|
||||
}
|
||||
setGraceIndex(graceIndex(e));
|
||||
setNote(note(e));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
@ -224,6 +185,96 @@ Location Location::positionForElement(const Element* e, bool absfrac)
|
|||
return i;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Location::track
|
||||
//---------------------------------------------------------
|
||||
|
||||
int Location::track(const Element* e)
|
||||
{
|
||||
int track = e->track();
|
||||
if (track < 0) {
|
||||
const MeasureBase* mb = e->findMeasureBase();
|
||||
if (mb && !mb->isMeasure()) {
|
||||
// Such elements are written in the first staff,
|
||||
// see writeMeasure() in scorefile.cpp
|
||||
track = 0;
|
||||
}
|
||||
}
|
||||
return track;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Location::measure
|
||||
//---------------------------------------------------------
|
||||
|
||||
int Location::measure(const Element* e)
|
||||
{
|
||||
const Measure* m = toMeasure(e->findMeasure());
|
||||
if (m)
|
||||
return m->measureIndex();
|
||||
qWarning("Location::measure: cannot find element's measure (%s)", e->name());
|
||||
return 0;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Location::graceIndex
|
||||
//---------------------------------------------------------
|
||||
|
||||
int Location::graceIndex(const Element* e)
|
||||
{
|
||||
if (e->isChord() || (e->parent() && e->parent()->isChord())) {
|
||||
const Chord* ch = e->isChord() ? toChord(e) : toChord(e->parent());
|
||||
if (ch->isGrace())
|
||||
return ch->graceIndex();
|
||||
}
|
||||
return absDefaults.graceIndex();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Location::note
|
||||
//---------------------------------------------------------
|
||||
|
||||
int Location::note(const Element* e)
|
||||
{
|
||||
if (e->isNote()) {
|
||||
const Note* n = toNote(e);
|
||||
const std::vector<Note*>& notes = n->chord()->notes();
|
||||
if (notes.size() == 1)
|
||||
return 0;
|
||||
int noteIdx;
|
||||
for (noteIdx = 0; noteIdx < int(notes.size()); ++noteIdx) {
|
||||
if (n == notes.at(noteIdx))
|
||||
break;
|
||||
}
|
||||
return noteIdx;
|
||||
}
|
||||
return absDefaults.note();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Location::getLocationProperty
|
||||
//---------------------------------------------------------
|
||||
|
||||
QVariant Location::getLocationProperty(Pid pid, const Element* start, const Element* end)
|
||||
{
|
||||
switch(pid) {
|
||||
case Pid::LOCATION_STAVES:
|
||||
return (track(start) / VOICES) - (track(end) / VOICES);
|
||||
case Pid::LOCATION_VOICES:
|
||||
return (track(start) % VOICES) - (track(end) / VOICES);
|
||||
case Pid::LOCATION_MEASURES:
|
||||
return measure(end) - measure(start);
|
||||
case Pid::LOCATION_FRACTIONS:
|
||||
return end->rfrac() - start->rfrac();
|
||||
case Pid::LOCATION_GRACE:
|
||||
return graceIndex(end) - graceIndex(end);
|
||||
case Pid::LOCATION_NOTE:
|
||||
return note(start) - note(end);
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Location::operator==
|
||||
//---------------------------------------------------------
|
||||
|
|
|
@ -23,6 +23,8 @@ class Element;
|
|||
class XmlReader;
|
||||
class XmlWriter;
|
||||
|
||||
enum class Pid;
|
||||
|
||||
class Location {
|
||||
int _staff;
|
||||
int _voice;
|
||||
|
@ -32,6 +34,11 @@ class Location {
|
|||
int _note;
|
||||
bool _rel;
|
||||
|
||||
static int track(const Element* e);
|
||||
static int measure(const Element* e);
|
||||
static int graceIndex(const Element* e);
|
||||
static int note(const Element* e);
|
||||
|
||||
public:
|
||||
constexpr Location(int staff, int voice, int measure, Fraction frac, int graceIndex, int note, bool rel)
|
||||
: _staff(staff), _voice(voice), _measure(measure), _frac(frac), _graceIndex(graceIndex), _note(note), _rel(rel) {}
|
||||
|
@ -67,6 +74,7 @@ class Location {
|
|||
void fillPositionForElement(const Element* e, bool absfrac = true);
|
||||
static Location forElement(const Element* e, bool absfrac = true);
|
||||
static Location positionForElement(const Element* e, bool absfrac = true);
|
||||
static QVariant getLocationProperty(Pid pid, const Element* start, const Element* end);
|
||||
|
||||
bool operator==(const Location& other) const;
|
||||
bool operator!=(const Location& other) const { return !(*this == other); }
|
||||
|
|
|
@ -85,7 +85,7 @@ void Lyrics::write(XmlWriter& xml) const
|
|||
{
|
||||
if (!xml.canWrite(this))
|
||||
return;
|
||||
xml.stag("Lyrics");
|
||||
xml.stag(this);
|
||||
writeProperty(xml, Pid::VERSE);
|
||||
if (_syllabic != Syllabic::SINGLE) {
|
||||
static const char* sl[] = {
|
||||
|
|
|
@ -204,7 +204,7 @@ void Marker::read(XmlReader& e)
|
|||
|
||||
void Marker::write(XmlWriter& xml) const
|
||||
{
|
||||
xml.stag(name());
|
||||
xml.stag(this);
|
||||
TextBase::writeProperties(xml);
|
||||
xml.tag("label", _label);
|
||||
xml.etag();
|
||||
|
|
|
@ -1760,10 +1760,10 @@ void Measure::write(XmlWriter& xml, int staff, bool writeSystemElements, bool fo
|
|||
}
|
||||
if (_len != _timesig) {
|
||||
// this is an irregular measure
|
||||
xml.stag(QString("Measure len=\"%1/%2\"").arg(_len.numerator()).arg(_len.denominator()));
|
||||
xml.stag(this, QString("len=\"%1/%2\"").arg(_len.numerator()).arg(_len.denominator()));
|
||||
}
|
||||
else
|
||||
xml.stag("Measure");
|
||||
xml.stag(this);
|
||||
|
||||
xml.setCurTick(tick());
|
||||
xml.setCurTrack(staff * VOICES);
|
||||
|
@ -1784,7 +1784,7 @@ void Measure::write(XmlWriter& xml, int staff, bool writeSystemElements, bool fo
|
|||
qreal _spatium = spatium();
|
||||
MStaff* mstaff = _mstaves[staff];
|
||||
if (mstaff->noText() && !mstaff->noText()->generated()) {
|
||||
xml.stag("MeasureNumber");
|
||||
xml.stag("MeasureNumber", mstaff->noText());
|
||||
mstaff->noText()->writeProperties(xml);
|
||||
xml.etag();
|
||||
}
|
||||
|
|
|
@ -258,6 +258,9 @@ void MScore::init()
|
|||
#endif
|
||||
qRegisterMetaType<Fraction>("Fraction");
|
||||
|
||||
if (!QMetaType::registerConverter<Fraction, QString>(&Fraction::toString))
|
||||
qFatal("registerConverter Fraction::toString failed");
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
QDir dir(QCoreApplication::applicationDirPath() + QString("/../" INSTALL_NAME));
|
||||
_globalShare = dir.absolutePath() + "/";
|
||||
|
|
|
@ -1177,7 +1177,7 @@ void Note::draw(QPainter* painter) const
|
|||
|
||||
void Note::write(XmlWriter& xml) const
|
||||
{
|
||||
xml.stag("Note");
|
||||
xml.stag(this);
|
||||
Element::writeProperties(xml);
|
||||
|
||||
if (_accidental)
|
||||
|
@ -2665,6 +2665,27 @@ QVariant Note::propertyDefault(Pid propertyId) const
|
|||
return Element::propertyDefault(propertyId);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// propertyUserValue
|
||||
//---------------------------------------------------------
|
||||
|
||||
QString Note::propertyUserValue(Pid pid) const
|
||||
{
|
||||
switch(pid) {
|
||||
case Pid::PITCH:
|
||||
return tpcUserName();
|
||||
case Pid::TPC1:
|
||||
case Pid::TPC2:
|
||||
{
|
||||
int idx = (pid == Pid::TPC1) ? 0 : 1;
|
||||
int tpc = _tpc[idx];
|
||||
return tpc2name(tpc, NoteSpellingType::STANDARD, NoteCaseType::AUTO, false);
|
||||
}
|
||||
default:
|
||||
return Element::propertyUserValue(pid);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// undoSetFret
|
||||
//---------------------------------------------------------
|
||||
|
|
|
@ -465,6 +465,7 @@ class Note final : public Element {
|
|||
virtual QVariant getProperty(Pid propertyId) const override;
|
||||
virtual bool setProperty(Pid propertyId, const QVariant&) override;
|
||||
virtual QVariant propertyDefault(Pid) const override;
|
||||
virtual QString propertyUserValue(Pid) const override;
|
||||
|
||||
bool mark() const { return _mark; }
|
||||
void setMark(bool v) const { _mark = v; }
|
||||
|
|
|
@ -255,7 +255,7 @@ void Ottava::write(XmlWriter& xml) const
|
|||
{
|
||||
if (!xml.canWrite(this))
|
||||
return;
|
||||
xml.stag(name());
|
||||
xml.stag(this);
|
||||
xml.tag("subtype", ottavaDefault[int(ottavaType())].name);
|
||||
// for (const StyledProperty& spp : *styledProperties())
|
||||
// writeProperty(xml, spp.pid);
|
||||
|
|
|
@ -418,7 +418,7 @@ bool Page::isOdd() const
|
|||
|
||||
void Page::write(XmlWriter& xml) const
|
||||
{
|
||||
xml.stag("Page");
|
||||
xml.stag(this);
|
||||
foreach(System* system, _systems) {
|
||||
system->write(xml);
|
||||
}
|
||||
|
|
|
@ -106,7 +106,7 @@ void PalmMute::write(XmlWriter& xml) const
|
|||
{
|
||||
if (!xml.canWrite(this))
|
||||
return;
|
||||
xml.stag(name());
|
||||
xml.stag(this);
|
||||
|
||||
for (const StyledProperty& spp : *styledProperties())
|
||||
writeProperty(xml, spp.pid);
|
||||
|
|
|
@ -109,7 +109,7 @@ void Part::read(XmlReader& e)
|
|||
|
||||
void Part::write(XmlWriter& xml) const
|
||||
{
|
||||
xml.stag("Part");
|
||||
xml.stag(this);
|
||||
foreach(const Staff* staff, _staves)
|
||||
staff->write(xml);
|
||||
if (!_show)
|
||||
|
|
|
@ -122,7 +122,7 @@ void Pedal::write(XmlWriter& xml) const
|
|||
{
|
||||
if (!xml.canWrite(this))
|
||||
return;
|
||||
xml.stag(name());
|
||||
xml.stag(this);
|
||||
|
||||
for (auto i : {
|
||||
Pid::END_HOOK_TYPE,
|
||||
|
|
|
@ -32,6 +32,7 @@ struct PropertyMetaData {
|
|||
bool link; // link this property for linked elements
|
||||
const char* name; // xml name of property
|
||||
P_TYPE type;
|
||||
const char* userName; // user-visible name of property
|
||||
};
|
||||
|
||||
//
|
||||
|
@ -39,278 +40,288 @@ struct PropertyMetaData {
|
|||
//
|
||||
//
|
||||
static constexpr PropertyMetaData propertyList[] = {
|
||||
{ Pid::SUBTYPE, "subtype", false, "subtype", P_TYPE::INT },
|
||||
{ Pid::SELECTED, "selected", false, "selected", P_TYPE::BOOL },
|
||||
{ Pid::GENERATED, "generated", false, "generated", P_TYPE::BOOL },
|
||||
{ Pid::COLOR, "color", false, "color", P_TYPE::COLOR },
|
||||
{ Pid::VISIBLE, "visible", false, "visible", P_TYPE::BOOL },
|
||||
{ Pid::Z, "z", false, "z", P_TYPE::INT },
|
||||
{ Pid::SMALL, "small", false, "small", P_TYPE::BOOL },
|
||||
{ Pid::SHOW_COURTESY, "show_courtesy", false, "showCourtesy", P_TYPE::INT },
|
||||
{ Pid::LINE_TYPE, "line_type", false, "lineType", P_TYPE::INT },
|
||||
{ Pid::PITCH, "pitch", true, "pitch", P_TYPE::INT },
|
||||
{ Pid::SUBTYPE, "subtype", false, "subtype", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "subtype") },
|
||||
{ Pid::SELECTED, "selected", false, "selected", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "selected") },
|
||||
{ Pid::GENERATED, "generated", false, "generated", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "generated") },
|
||||
{ Pid::COLOR, "color", false, "color", P_TYPE::COLOR, QT_TRANSLATE_NOOP("propertyName", "color") },
|
||||
{ Pid::VISIBLE, "visible", false, "visible", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "visible") },
|
||||
{ Pid::Z, "z", false, "z", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "z") },
|
||||
{ Pid::SMALL, "small", false, "small", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "small") },
|
||||
{ Pid::SHOW_COURTESY, "show_courtesy", false, "showCourtesy", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "show courtesy") },
|
||||
{ Pid::LINE_TYPE, "line_type", false, "lineType", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "line type") },
|
||||
{ Pid::PITCH, "pitch", true, "pitch", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "pitch") },
|
||||
|
||||
{ Pid::TPC1, "tpc1", true, "tpc", P_TYPE::INT },
|
||||
{ Pid::TPC2, "tpc2", true, "tpc2", P_TYPE::INT },
|
||||
{ Pid::LINE, "line", false, "line", P_TYPE::INT },
|
||||
{ Pid::FIXED, "fixed", false, "fixed", P_TYPE::BOOL },
|
||||
{ Pid::FIXED_LINE, "fixed_line", false, "fixedLine", P_TYPE::INT },
|
||||
{ Pid::HEAD_TYPE, "head_type", false, "headType", P_TYPE::HEAD_TYPE },
|
||||
{ Pid::HEAD_GROUP, "head_group", false, "head", P_TYPE::HEAD_GROUP },
|
||||
{ Pid::VELO_TYPE, "velo_type", false, "veloType", P_TYPE::VALUE_TYPE },
|
||||
{ Pid::VELO_OFFSET, "velo_offset", false, "velocity", P_TYPE::INT },
|
||||
{ Pid::ARTICULATION_ANCHOR, "articulation_anchor", false, "anchor", P_TYPE::INT },
|
||||
{ Pid::TPC1, "tpc1", true, "tpc", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "tonal pitch class") },
|
||||
{ Pid::TPC2, "tpc2", true, "tpc2", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "tonal pitch class") },
|
||||
{ Pid::LINE, "line", false, "line", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "line") },
|
||||
{ Pid::FIXED, "fixed", false, "fixed", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "fixed") },
|
||||
{ Pid::FIXED_LINE, "fixed_line", false, "fixedLine", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "fixed line") },
|
||||
{ Pid::HEAD_TYPE, "head_type", false, "headType", P_TYPE::HEAD_TYPE, QT_TRANSLATE_NOOP("propertyName", "head type") },
|
||||
{ Pid::HEAD_GROUP, "head_group", false, "head", P_TYPE::HEAD_GROUP, QT_TRANSLATE_NOOP("propertyName", "head") },
|
||||
{ Pid::VELO_TYPE, "velo_type", false, "veloType", P_TYPE::VALUE_TYPE, QT_TRANSLATE_NOOP("propertyName", "velocity type") },
|
||||
{ Pid::VELO_OFFSET, "velo_offset", false, "velocity", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "velocity") },
|
||||
{ Pid::ARTICULATION_ANCHOR, "articulation_anchor", false, "anchor", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "anchor") },
|
||||
|
||||
{ Pid::DIRECTION, "direction", false, "direction", P_TYPE::DIRECTION },
|
||||
{ Pid::STEM_DIRECTION, "stem_direction", false, "StemDirection", P_TYPE::DIRECTION },
|
||||
{ Pid::NO_STEM, "no_stem", false, "noStem", P_TYPE::INT },
|
||||
{ Pid::SLUR_DIRECTION, "slur_direction", false, "up", P_TYPE::DIRECTION },
|
||||
{ Pid::LEADING_SPACE, "leading_space", false, "leadingSpace", P_TYPE::SPATIUM },
|
||||
{ Pid::DISTRIBUTE, "distribute", false, "distribute", P_TYPE::BOOL },
|
||||
{ Pid::MIRROR_HEAD, "mirror_head", false, "mirror", P_TYPE::DIRECTION_H },
|
||||
{ Pid::DOT_POSITION, "dot_position", false, "dotPosition", P_TYPE::DIRECTION },
|
||||
{ Pid::TUNING, "tuning", false, "tuning", P_TYPE::REAL },
|
||||
{ Pid::PAUSE, "pause", true, "pause", P_TYPE::REAL },
|
||||
{ Pid::DIRECTION, "direction", false, "direction", P_TYPE::DIRECTION, QT_TRANSLATE_NOOP("propertyName", "direction") },
|
||||
{ Pid::STEM_DIRECTION, "stem_direction", false, "StemDirection", P_TYPE::DIRECTION, QT_TRANSLATE_NOOP("propertyName", "stem direction") },
|
||||
{ Pid::NO_STEM, "no_stem", false, "noStem", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "no stem") },
|
||||
{ Pid::SLUR_DIRECTION, "slur_direction", false, "up", P_TYPE::DIRECTION, QT_TRANSLATE_NOOP("propertyName", "up") },
|
||||
{ Pid::LEADING_SPACE, "leading_space", false, "leadingSpace", P_TYPE::SPATIUM, QT_TRANSLATE_NOOP("propertyName", "leading space") },
|
||||
{ Pid::DISTRIBUTE, "distribute", false, "distribute", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "distributed") },
|
||||
{ Pid::MIRROR_HEAD, "mirror_head", false, "mirror", P_TYPE::DIRECTION_H, QT_TRANSLATE_NOOP("propertyName", "mirror") },
|
||||
{ Pid::DOT_POSITION, "dot_position", false, "dotPosition", P_TYPE::DIRECTION, QT_TRANSLATE_NOOP("propertyName", "dot position") },
|
||||
{ Pid::TUNING, "tuning", false, "tuning", P_TYPE::REAL, QT_TRANSLATE_NOOP("propertyName", "tuning") },
|
||||
{ Pid::PAUSE, "pause", true, "pause", P_TYPE::REAL, QT_TRANSLATE_NOOP("propertyName", "pause") },
|
||||
|
||||
{ Pid::BARLINE_TYPE, "barline_type", false, "subtype", P_TYPE::BARLINE_TYPE },
|
||||
{ Pid::BARLINE_SPAN, "barline_span", false, "span", P_TYPE::BOOL },
|
||||
{ Pid::BARLINE_SPAN_FROM, "barline_span_from", false, "spanFromOffset", P_TYPE::INT },
|
||||
{ Pid::BARLINE_SPAN_TO, "barline_span_to", false, "spanToOffset", P_TYPE::INT },
|
||||
{ Pid::OFFSET, "offset", false, "offset", P_TYPE::POINT_SP_MM },
|
||||
{ Pid::FRET, "fret", true, "fret", P_TYPE::INT },
|
||||
{ Pid::STRING, "string", true, "string", P_TYPE::INT },
|
||||
{ Pid::GHOST, "ghost", true, "ghost", P_TYPE::BOOL },
|
||||
{ Pid::PLAY, "play", false, "play", P_TYPE::BOOL },
|
||||
{ Pid::TIMESIG_NOMINAL, "timesig_nominal", false, 0, P_TYPE::FRACTION },
|
||||
{ Pid::BARLINE_TYPE, "barline_type", false, "subtype", P_TYPE::BARLINE_TYPE, QT_TRANSLATE_NOOP("propertyName", "subtype") },
|
||||
{ Pid::BARLINE_SPAN, "barline_span", false, "span", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "span") },
|
||||
{ Pid::BARLINE_SPAN_FROM, "barline_span_from", false, "spanFromOffset", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "span from") },
|
||||
{ Pid::BARLINE_SPAN_TO, "barline_span_to", false, "spanToOffset", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "span to") },
|
||||
{ Pid::OFFSET, "offset", false, "offset", P_TYPE::POINT_SP_MM, QT_TRANSLATE_NOOP("propertyName", "offset") },
|
||||
{ Pid::FRET, "fret", true, "fret", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "fret") },
|
||||
{ Pid::STRING, "string", true, "string", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "string") },
|
||||
{ Pid::GHOST, "ghost", true, "ghost", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "ghost") },
|
||||
{ Pid::PLAY, "play", false, "play", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "played") },
|
||||
{ Pid::TIMESIG_NOMINAL, "timesig_nominal", false, 0, P_TYPE::FRACTION, QT_TRANSLATE_NOOP("propertyName", "nominal time signature") },
|
||||
|
||||
{ Pid::TIMESIG_ACTUAL, "timesig_actual", true, 0, P_TYPE::FRACTION },
|
||||
{ Pid::NUMBER_TYPE, "number_type", false, "numberType", P_TYPE::INT },
|
||||
{ Pid::BRACKET_TYPE, "bracket_type", false, "bracketType", P_TYPE::INT },
|
||||
{ Pid::NORMAL_NOTES, "normal_notes", false, "normalNotes", P_TYPE::INT },
|
||||
{ Pid::ACTUAL_NOTES, "actual_notes", false, "actualNotes", P_TYPE::INT },
|
||||
{ Pid::P1, "p1", false, "p1", P_TYPE::POINT_SP },
|
||||
{ Pid::P2, "p2", false, "p2", P_TYPE::POINT_SP },
|
||||
{ Pid::GROW_LEFT, "grow_left", false, "growLeft", P_TYPE::REAL },
|
||||
{ Pid::GROW_RIGHT, "grow_right", false, "growRight", P_TYPE::REAL },
|
||||
{ Pid::BOX_HEIGHT, "box_height", false, "height", P_TYPE::SPATIUM },
|
||||
{ Pid::TIMESIG_ACTUAL, "timesig_actual", true, 0, P_TYPE::FRACTION, QT_TRANSLATE_NOOP("propertyName", "actual time signature") },
|
||||
{ Pid::NUMBER_TYPE, "number_type", false, "numberType", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "number type") },
|
||||
{ Pid::BRACKET_TYPE, "bracket_type", false, "bracketType", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "bracket type") },
|
||||
{ Pid::NORMAL_NOTES, "normal_notes", false, "normalNotes", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "normal notes") },
|
||||
{ Pid::ACTUAL_NOTES, "actual_notes", false, "actualNotes", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "actual notes") },
|
||||
{ Pid::P1, "p1", false, "p1", P_TYPE::POINT_SP, QT_TRANSLATE_NOOP("propertyName", "p1") },
|
||||
{ Pid::P2, "p2", false, "p2", P_TYPE::POINT_SP, QT_TRANSLATE_NOOP("propertyName", "p2") },
|
||||
{ Pid::GROW_LEFT, "grow_left", false, "growLeft", P_TYPE::REAL, QT_TRANSLATE_NOOP("propertyName", "grow left") },
|
||||
{ Pid::GROW_RIGHT, "grow_right", false, "growRight", P_TYPE::REAL, QT_TRANSLATE_NOOP("propertyName", "grow right") },
|
||||
{ Pid::BOX_HEIGHT, "box_height", false, "height", P_TYPE::SPATIUM, QT_TRANSLATE_NOOP("propertyName", "height") },
|
||||
|
||||
{ Pid::BOX_WIDTH, "box_width", false, "width", P_TYPE::SPATIUM },
|
||||
{ Pid::TOP_GAP, "top_gap", false, "topGap", P_TYPE::SP_REAL },
|
||||
{ Pid::BOTTOM_GAP, "bottom_gap", false, "bottomGap", P_TYPE::SP_REAL },
|
||||
{ Pid::LEFT_MARGIN, "left_margin", false, "leftMargin", P_TYPE::REAL },
|
||||
{ Pid::RIGHT_MARGIN, "right_margin", false, "rightMargin", P_TYPE::REAL },
|
||||
{ Pid::TOP_MARGIN, "top_margin", false, "topMargin", P_TYPE::REAL },
|
||||
{ Pid::BOTTOM_MARGIN, "bottom_margin", false, "bottomMargin", P_TYPE::REAL },
|
||||
{ Pid::LAYOUT_BREAK, "layout_break", false, "subtype", P_TYPE::LAYOUT_BREAK },
|
||||
{ Pid::AUTOSCALE, "autoscale", false, "autoScale", P_TYPE::BOOL },
|
||||
{ Pid::SIZE, "size", false, "size", P_TYPE::SIZE },
|
||||
{ Pid::BOX_WIDTH, "box_width", false, "width", P_TYPE::SPATIUM, QT_TRANSLATE_NOOP("propertyName", "width") },
|
||||
{ Pid::TOP_GAP, "top_gap", false, "topGap", P_TYPE::SP_REAL, QT_TRANSLATE_NOOP("propertyName", "top gap") },
|
||||
{ Pid::BOTTOM_GAP, "bottom_gap", false, "bottomGap", P_TYPE::SP_REAL, QT_TRANSLATE_NOOP("propertyName", "bottom gap") },
|
||||
{ Pid::LEFT_MARGIN, "left_margin", false, "leftMargin", P_TYPE::REAL, QT_TRANSLATE_NOOP("propertyName", "left margin") },
|
||||
{ Pid::RIGHT_MARGIN, "right_margin", false, "rightMargin", P_TYPE::REAL, QT_TRANSLATE_NOOP("propertyName", "right margin") },
|
||||
{ Pid::TOP_MARGIN, "top_margin", false, "topMargin", P_TYPE::REAL, QT_TRANSLATE_NOOP("propertyName", "top margin") },
|
||||
{ Pid::BOTTOM_MARGIN, "bottom_margin", false, "bottomMargin", P_TYPE::REAL, QT_TRANSLATE_NOOP("propertyName", "bottom margin") },
|
||||
{ Pid::LAYOUT_BREAK, "layout_break", false, "subtype", P_TYPE::LAYOUT_BREAK, QT_TRANSLATE_NOOP("propertyName", "subtype") },
|
||||
{ Pid::AUTOSCALE, "autoscale", false, "autoScale", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "autoscale") },
|
||||
{ Pid::SIZE, "size", false, "size", P_TYPE::SIZE, QT_TRANSLATE_NOOP("propertyName", "size") },
|
||||
|
||||
{ Pid::SCALE, "scale", false, "scale", P_TYPE::SCALE },
|
||||
{ Pid::LOCK_ASPECT_RATIO, "lock_aspect_ratio", false, "lockAspectRatio", P_TYPE::BOOL },
|
||||
{ Pid::SIZE_IS_SPATIUM, "size_is_spatium", false, "sizeIsSpatium", P_TYPE::BOOL },
|
||||
{ Pid::TEXT, "text", true, 0, P_TYPE::STRING },
|
||||
{ Pid::HTML_TEXT, "html_text", false, 0, P_TYPE::STRING },
|
||||
{ Pid::USER_MODIFIED, "user_modified", false, 0, P_TYPE::BOOL },
|
||||
{ Pid::BEAM_POS, "beam_pos", false, 0, P_TYPE::POINT },
|
||||
{ Pid::BEAM_MODE, "beam_mode", true, "BeamMode", P_TYPE::BEAM_MODE },
|
||||
{ Pid::BEAM_NO_SLOPE, "beam_no_slope", true, "noSlope", P_TYPE::BOOL },
|
||||
{ Pid::USER_LEN, "user_len", false, "userLen", P_TYPE::SP_REAL },
|
||||
{ Pid::SCALE, "scale", false, "scale", P_TYPE::SCALE, QT_TRANSLATE_NOOP("propertyName", "scale") },
|
||||
{ Pid::LOCK_ASPECT_RATIO, "lock_aspect_ratio", false, "lockAspectRatio", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "aspect ratio locked") },
|
||||
{ Pid::SIZE_IS_SPATIUM, "size_is_spatium", false, "sizeIsSpatium", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "size is spatium") },
|
||||
{ Pid::TEXT, "text", true, 0, P_TYPE::STRING, QT_TRANSLATE_NOOP("propertyName", "text") },
|
||||
{ Pid::HTML_TEXT, "html_text", false, 0, P_TYPE::STRING, "" },
|
||||
{ Pid::USER_MODIFIED, "user_modified", false, 0, P_TYPE::BOOL, "" },
|
||||
{ Pid::BEAM_POS, "beam_pos", false, 0, P_TYPE::POINT, QT_TRANSLATE_NOOP("propertyName", "beam position") },
|
||||
{ Pid::BEAM_MODE, "beam_mode", true, "BeamMode", P_TYPE::BEAM_MODE, QT_TRANSLATE_NOOP("propertyName", "beam mode") },
|
||||
{ Pid::BEAM_NO_SLOPE, "beam_no_slope", true, "noSlope", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "without slope") },
|
||||
{ Pid::USER_LEN, "user_len", false, "userLen", P_TYPE::SP_REAL, QT_TRANSLATE_NOOP("propertyName", "length") },
|
||||
|
||||
{ Pid::SPACE, "space", false, "space", P_TYPE::SP_REAL },
|
||||
{ Pid::TEMPO, "tempo", true, "tempo", P_TYPE::TEMPO },
|
||||
{ Pid::TEMPO_FOLLOW_TEXT, "tempo_follow_text", true, "followText", P_TYPE::BOOL },
|
||||
{ Pid::ACCIDENTAL_BRACKET, "accidental_bracket", false, "bracket", P_TYPE::INT },
|
||||
{ Pid::NUMERATOR_STRING, "numerator_string", false, "textN", P_TYPE::STRING },
|
||||
{ Pid::DENOMINATOR_STRING, "denominator_string", false, "textD", P_TYPE::STRING },
|
||||
{ Pid::FBPREFIX, "fbprefix", false, "prefix", P_TYPE::INT },
|
||||
{ Pid::FBDIGIT, "fbdigit", false, "digit", P_TYPE::INT },
|
||||
{ Pid::FBSUFFIX, "fbsuffix", false, "suffix", P_TYPE::INT },
|
||||
{ Pid::FBCONTINUATIONLINE, "fbcontinuationline", false, "continuationLine", P_TYPE::INT },
|
||||
{ Pid::SPACE, "space", false, "space", P_TYPE::SP_REAL, QT_TRANSLATE_NOOP("propertyName", "space") },
|
||||
{ Pid::TEMPO, "tempo", true, "tempo", P_TYPE::TEMPO, QT_TRANSLATE_NOOP("propertyName", "tempo") },
|
||||
{ Pid::TEMPO_FOLLOW_TEXT, "tempo_follow_text", true, "followText", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "following text") },
|
||||
{ Pid::ACCIDENTAL_BRACKET, "accidental_bracket", false, "bracket", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "bracket") },
|
||||
{ Pid::NUMERATOR_STRING, "numerator_string", false, "textN", P_TYPE::STRING, QT_TRANSLATE_NOOP("propertyName", "numerator string") },
|
||||
{ Pid::DENOMINATOR_STRING, "denominator_string", false, "textD", P_TYPE::STRING, QT_TRANSLATE_NOOP("propertyName", "denominator string") },
|
||||
{ Pid::FBPREFIX, "fbprefix", false, "prefix", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "prefix") },
|
||||
{ Pid::FBDIGIT, "fbdigit", false, "digit", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "digit") },
|
||||
{ Pid::FBSUFFIX, "fbsuffix", false, "suffix", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "suffix") },
|
||||
{ Pid::FBCONTINUATIONLINE, "fbcontinuationline", false, "continuationLine", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "continuation line") },
|
||||
|
||||
{ Pid::FBPARENTHESIS1, "fbparenthesis1", false, "", P_TYPE::INT },
|
||||
{ Pid::FBPARENTHESIS2, "fbparenthesis2", false, "", P_TYPE::INT },
|
||||
{ Pid::FBPARENTHESIS3, "fbparenthesis3", false, "", P_TYPE::INT },
|
||||
{ Pid::FBPARENTHESIS4, "fbparenthesis4", false, "", P_TYPE::INT },
|
||||
{ Pid::FBPARENTHESIS5, "fbparenthesis5", false, "", P_TYPE::INT },
|
||||
{ Pid::OTTAVA_TYPE, "ottava_type", true, "", P_TYPE::INT },
|
||||
{ Pid::NUMBERS_ONLY, "numbers_only", false, "numbersOnly", P_TYPE::BOOL },
|
||||
{ Pid::TRILL_TYPE, "trill_type", false, "", P_TYPE::INT },
|
||||
{ Pid::VIBRATO_TYPE, "vibrato_type", false, "", P_TYPE::INT },
|
||||
{ Pid::HAIRPIN_CIRCLEDTIP, "hairpin_circledtip", false, "hairpinCircledTip", P_TYPE::BOOL },
|
||||
{ Pid::FBPARENTHESIS1, "fbparenthesis1", false, "", P_TYPE::INT, "" },
|
||||
{ Pid::FBPARENTHESIS2, "fbparenthesis2", false, "", P_TYPE::INT, "" },
|
||||
{ Pid::FBPARENTHESIS3, "fbparenthesis3", false, "", P_TYPE::INT, "" },
|
||||
{ Pid::FBPARENTHESIS4, "fbparenthesis4", false, "", P_TYPE::INT, "" },
|
||||
{ Pid::FBPARENTHESIS5, "fbparenthesis5", false, "", P_TYPE::INT, "" },
|
||||
{ Pid::OTTAVA_TYPE, "ottava_type", true, "", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "ottava type") },
|
||||
{ Pid::NUMBERS_ONLY, "numbers_only", false, "numbersOnly", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "numbers only") },
|
||||
{ Pid::TRILL_TYPE, "trill_type", false, "", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "trill type") },
|
||||
{ Pid::VIBRATO_TYPE, "vibrato_type", false, "", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "vibrato type") },
|
||||
{ Pid::HAIRPIN_CIRCLEDTIP, "hairpin_circledtip", false, "hairpinCircledTip", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "hairpin with circled tip") },
|
||||
|
||||
{ Pid::HAIRPIN_TYPE, "hairpin_type", true, "", P_TYPE::INT },
|
||||
{ Pid::HAIRPIN_HEIGHT, "hairpin_height", false, "hairpinHeight", P_TYPE::SPATIUM },
|
||||
{ Pid::HAIRPIN_CONT_HEIGHT, "hairpin_cont_height", false, "hairpinContHeight", P_TYPE::SPATIUM },
|
||||
{ Pid::VELO_CHANGE, "velo_change", true, "veloChange", P_TYPE::INT },
|
||||
{ Pid::DYNAMIC_RANGE, "dynamic_range", true, "dynType", P_TYPE::INT },
|
||||
{ Pid::PLACEMENT, "placement", false, "placement", P_TYPE::PLACEMENT },
|
||||
{ Pid::VELOCITY, "velocity", false, "velocity", P_TYPE::INT },
|
||||
{ Pid::JUMP_TO, "jump_to", true, "jumpTo", P_TYPE::STRING },
|
||||
{ Pid::PLAY_UNTIL, "play_until", true, "playUntil", P_TYPE::STRING },
|
||||
{ Pid::CONTINUE_AT, "continue_at", true, "continueAt", P_TYPE::STRING },
|
||||
{ Pid::HAIRPIN_TYPE, "hairpin_type", true, "", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "hairpin type") },
|
||||
{ Pid::HAIRPIN_HEIGHT, "hairpin_height", false, "hairpinHeight", P_TYPE::SPATIUM, QT_TRANSLATE_NOOP("propertyName", "hairpin height") },
|
||||
{ Pid::HAIRPIN_CONT_HEIGHT, "hairpin_cont_height", false, "hairpinContHeight", P_TYPE::SPATIUM, QT_TRANSLATE_NOOP("propertyName", "hairpin cont height") },
|
||||
{ Pid::VELO_CHANGE, "velo_change", true, "veloChange", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "velocity change") },
|
||||
{ Pid::DYNAMIC_RANGE, "dynamic_range", true, "dynType", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "dynamic range") },
|
||||
{ Pid::PLACEMENT, "placement", false, "placement", P_TYPE::PLACEMENT, QT_TRANSLATE_NOOP("propertyName", "placement") },
|
||||
{ Pid::VELOCITY, "velocity", false, "velocity", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "velocity") },
|
||||
{ Pid::JUMP_TO, "jump_to", true, "jumpTo", P_TYPE::STRING, QT_TRANSLATE_NOOP("propertyName", "jump to") },
|
||||
{ Pid::PLAY_UNTIL, "play_until", true, "playUntil", P_TYPE::STRING, QT_TRANSLATE_NOOP("propertyName", "play until") },
|
||||
{ Pid::CONTINUE_AT, "continue_at", true, "continueAt", P_TYPE::STRING, QT_TRANSLATE_NOOP("propertyName", "continue at") },
|
||||
//100
|
||||
{ Pid::LABEL, "label", true, "label", P_TYPE::STRING },
|
||||
{ Pid::MARKER_TYPE, "marker_type", true, 0, P_TYPE::INT },
|
||||
{ Pid::ARP_USER_LEN1, "arp_user_len1", false, 0, P_TYPE::REAL },
|
||||
{ Pid::ARP_USER_LEN2, "arp_user_len2", false, 0, P_TYPE::REAL },
|
||||
{ Pid::REPEAT_END, "repeat_end", true, 0, P_TYPE::BOOL },
|
||||
{ Pid::REPEAT_START, "repeat_start", true, 0, P_TYPE::BOOL },
|
||||
{ Pid::REPEAT_JUMP, "repeat_jump", true, 0, P_TYPE::BOOL },
|
||||
{ Pid::MEASURE_NUMBER_MODE, "measure_number_mode", false, "measureNumberMode", P_TYPE::INT },
|
||||
{ Pid::GLISS_TYPE, "gliss_type", false, "subtype", P_TYPE::INT },
|
||||
{ Pid::GLISS_TEXT, "gliss_text", false, 0, P_TYPE::STRING },
|
||||
{ Pid::LABEL, "label", true, "label", P_TYPE::STRING, QT_TRANSLATE_NOOP("propertyName", "label") },
|
||||
{ Pid::MARKER_TYPE, "marker_type", true, 0, P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "marker type") },
|
||||
{ Pid::ARP_USER_LEN1, "arp_user_len1", false, 0, P_TYPE::REAL, QT_TRANSLATE_NOOP("propertyName", "length 1") },
|
||||
{ Pid::ARP_USER_LEN2, "arp_user_len2", false, 0, P_TYPE::REAL, QT_TRANSLATE_NOOP("propertyName", "length 2") },
|
||||
{ Pid::REPEAT_END, "repeat_end", true, 0, P_TYPE::BOOL, "" },
|
||||
{ Pid::REPEAT_START, "repeat_start", true, 0, P_TYPE::BOOL, "" },
|
||||
{ Pid::REPEAT_JUMP, "repeat_jump", true, 0, P_TYPE::BOOL, "" },
|
||||
{ Pid::MEASURE_NUMBER_MODE, "measure_number_mode", false, "measureNumberMode", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "measure number mode") },
|
||||
{ Pid::GLISS_TYPE, "gliss_type", false, "subtype", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "subtype") },
|
||||
{ Pid::GLISS_TEXT, "gliss_text", false, 0, P_TYPE::STRING, QT_TRANSLATE_NOOP("propertyName", "text") },
|
||||
|
||||
{ Pid::GLISS_SHOW_TEXT, "gliss_show_text", false, 0, P_TYPE::BOOL },
|
||||
{ Pid::DIAGONAL, "diagonal", false, 0, P_TYPE::BOOL },
|
||||
{ Pid::GROUPS, "groups", false, 0, P_TYPE::GROUPS },
|
||||
{ Pid::LINE_STYLE, "line_style", false, "lineStyle", P_TYPE::INT },
|
||||
{ Pid::LINE_COLOR, "line_color", false, 0, P_TYPE::COLOR },
|
||||
{ Pid::LINE_WIDTH, "line_width", false, "lineWidth", P_TYPE::SP_REAL },
|
||||
{ Pid::LASSO_POS, "lasso_pos", false, 0, P_TYPE::POINT_MM },
|
||||
{ Pid::LASSO_SIZE, "lasso_size", false, 0, P_TYPE::SIZE_MM },
|
||||
{ Pid::TIME_STRETCH, "time_stretch", true, "timeStretch", P_TYPE::REAL },
|
||||
{ Pid::ORNAMENT_STYLE, "ornament_style", true, "ornamentStyle", P_TYPE::ORNAMENT_STYLE },
|
||||
{ Pid::GLISS_SHOW_TEXT, "gliss_show_text", false, 0, P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "showing text") },
|
||||
{ Pid::DIAGONAL, "diagonal", false, 0, P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "diagonal") },
|
||||
{ Pid::GROUPS, "groups", false, 0, P_TYPE::GROUPS, QT_TRANSLATE_NOOP("propertyName", "groups") },
|
||||
{ Pid::LINE_STYLE, "line_style", false, "lineStyle", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "line style") },
|
||||
{ Pid::LINE_COLOR, "line_color", false, 0, P_TYPE::COLOR, QT_TRANSLATE_NOOP("propertyName", "line color") },
|
||||
{ Pid::LINE_WIDTH, "line_width", false, "lineWidth", P_TYPE::SP_REAL, QT_TRANSLATE_NOOP("propertyName", "line width") },
|
||||
{ Pid::LASSO_POS, "lasso_pos", false, 0, P_TYPE::POINT_MM, QT_TRANSLATE_NOOP("propertyName", "lasso position") },
|
||||
{ Pid::LASSO_SIZE, "lasso_size", false, 0, P_TYPE::SIZE_MM, QT_TRANSLATE_NOOP("propertyName", "lasso size") },
|
||||
{ Pid::TIME_STRETCH, "time_stretch", true, "timeStretch", P_TYPE::REAL, QT_TRANSLATE_NOOP("propertyName", "time stretch") },
|
||||
{ Pid::ORNAMENT_STYLE, "ornament_style", true, "ornamentStyle", P_TYPE::ORNAMENT_STYLE, QT_TRANSLATE_NOOP("propertyName", "ornament style") },
|
||||
|
||||
{ Pid::TIMESIG, "timesig", false, 0, P_TYPE::FRACTION },
|
||||
{ Pid::TIMESIG_GLOBAL, "timesig_global", false, 0, P_TYPE::FRACTION },
|
||||
{ Pid::TIMESIG_STRETCH, "timesig_stretch", false, 0, P_TYPE::FRACTION },
|
||||
{ Pid::TIMESIG_TYPE, "timesig_type", true, "subtype", P_TYPE::INT },
|
||||
{ Pid::SPANNER_TICK, "spanner_tick", true, "tick", P_TYPE::INT },
|
||||
{ Pid::SPANNER_TICKS, "spanner_ticks", true, "ticks", P_TYPE::INT },
|
||||
{ Pid::SPANNER_TRACK2, "spanner_track2", true, "track2", P_TYPE::INT },
|
||||
{ Pid::OFFSET2, "user_off2", false, "userOff2", P_TYPE::POINT_SP },
|
||||
{ Pid::BREAK_MMR, "break_mmr", false, "breakMultiMeasureRest", P_TYPE::BOOL },
|
||||
{ Pid::REPEAT_COUNT, "repeat_count", true, "endRepeat", P_TYPE::INT },
|
||||
{ Pid::TIMESIG, "timesig", false, 0, P_TYPE::FRACTION, QT_TRANSLATE_NOOP("propertyName", "time signature") },
|
||||
{ Pid::TIMESIG_GLOBAL, "timesig_global", false, 0, P_TYPE::FRACTION, QT_TRANSLATE_NOOP("propertyName", "global time signature") },
|
||||
{ Pid::TIMESIG_STRETCH, "timesig_stretch", false, 0, P_TYPE::FRACTION, QT_TRANSLATE_NOOP("propertyName", "time signature stretch") },
|
||||
{ Pid::TIMESIG_TYPE, "timesig_type", true, "subtype", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "subtype") },
|
||||
{ Pid::SPANNER_TICK, "spanner_tick", true, "tick", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "tick") },
|
||||
{ Pid::SPANNER_TICKS, "spanner_ticks", true, "ticks", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "ticks") },
|
||||
{ Pid::SPANNER_TRACK2, "spanner_track2", true, "track2", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "track2") },
|
||||
{ Pid::OFFSET2, "user_off2", false, "userOff2", P_TYPE::POINT_SP, QT_TRANSLATE_NOOP("propertyName", "offset2") },
|
||||
{ Pid::BREAK_MMR, "break_mmr", false, "breakMultiMeasureRest", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "breaking multimeasure rest")},
|
||||
{ Pid::REPEAT_COUNT, "repeat_count", true, "endRepeat", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "end repeat") },
|
||||
|
||||
{ Pid::USER_STRETCH, "user_stretch", false, "stretch", P_TYPE::REAL },
|
||||
{ Pid::NO_OFFSET, "no_offset", false, "noOffset", P_TYPE::INT },
|
||||
{ Pid::IRREGULAR, "irregular", true, "irregular", P_TYPE::BOOL },
|
||||
{ Pid::ANCHOR, "anchor", false, "anchor", P_TYPE::INT },
|
||||
{ Pid::SLUR_UOFF1, "slur_uoff1", false, "o1", P_TYPE::POINT_SP },
|
||||
{ Pid::SLUR_UOFF2, "slur_uoff2", false, "o2", P_TYPE::POINT_SP },
|
||||
{ Pid::SLUR_UOFF3, "slur_uoff3", false, "o3", P_TYPE::POINT_SP },
|
||||
{ Pid::SLUR_UOFF4, "slur_uoff4", false, "o4", P_TYPE::POINT_SP },
|
||||
{ Pid::STAFF_MOVE, "staff_move", true, "staffMove", P_TYPE::INT },
|
||||
{ Pid::VERSE, "verse", true, "no", P_TYPE::ZERO_INT },
|
||||
{ Pid::USER_STRETCH, "user_stretch", false, "stretch", P_TYPE::REAL, QT_TRANSLATE_NOOP("propertyName", "stretch") },
|
||||
{ Pid::NO_OFFSET, "no_offset", false, "noOffset", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "numbering offset") },
|
||||
{ Pid::IRREGULAR, "irregular", true, "irregular", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "irregular") },
|
||||
{ Pid::ANCHOR, "anchor", false, "anchor", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "anchor") },
|
||||
{ Pid::SLUR_UOFF1, "slur_uoff1", false, "o1", P_TYPE::POINT_SP, QT_TRANSLATE_NOOP("propertyName", "o1") },
|
||||
{ Pid::SLUR_UOFF2, "slur_uoff2", false, "o2", P_TYPE::POINT_SP, QT_TRANSLATE_NOOP("propertyName", "o2") },
|
||||
{ Pid::SLUR_UOFF3, "slur_uoff3", false, "o3", P_TYPE::POINT_SP, QT_TRANSLATE_NOOP("propertyName", "o3") },
|
||||
{ Pid::SLUR_UOFF4, "slur_uoff4", false, "o4", P_TYPE::POINT_SP, QT_TRANSLATE_NOOP("propertyName", "o4") },
|
||||
{ Pid::STAFF_MOVE, "staff_move", true, "staffMove", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "staff move") },
|
||||
{ Pid::VERSE, "verse", true, "no", P_TYPE::ZERO_INT, QT_TRANSLATE_NOOP("propertyName", "verse") },
|
||||
|
||||
{ Pid::SYLLABIC, "syllabic", true, "syllabic", P_TYPE::INT },
|
||||
{ Pid::LYRIC_TICKS, "lyric_ticks", true, "ticks", P_TYPE::INT },
|
||||
{ Pid::VOLTA_ENDING, "volta_ending", true, "endings", P_TYPE::INT_LIST },
|
||||
{ Pid::LINE_VISIBLE, "line_visible", true, "lineVisible", P_TYPE::BOOL },
|
||||
{ Pid::MAG, "mag", false, "mag", P_TYPE::REAL },
|
||||
{ Pid::USE_DRUMSET, "use_drumset", false, "useDrumset", P_TYPE::BOOL },
|
||||
{ Pid::PART_VOLUME, "part_volume", false, "volume", P_TYPE::INT },
|
||||
{ Pid::PART_MUTE, "part_mute", false, "mute", P_TYPE::BOOL },
|
||||
{ Pid::PART_PAN, "part_pan", false, "pan", P_TYPE::INT },
|
||||
{ Pid::PART_REVERB, "part_reverb", false, "reverb", P_TYPE::INT },
|
||||
{ Pid::SYLLABIC, "syllabic", true, "syllabic", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "syllabic") },
|
||||
{ Pid::LYRIC_TICKS, "lyric_ticks", true, "ticks", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "ticks") },
|
||||
{ Pid::VOLTA_ENDING, "volta_ending", true, "endings", P_TYPE::INT_LIST, QT_TRANSLATE_NOOP("propertyName", "endings") },
|
||||
{ Pid::LINE_VISIBLE, "line_visible", true, "lineVisible", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "visible line") },
|
||||
{ Pid::MAG, "mag", false, "mag", P_TYPE::REAL, QT_TRANSLATE_NOOP("propertyName", "mag") },
|
||||
{ Pid::USE_DRUMSET, "use_drumset", false, "useDrumset", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "using drumset") },
|
||||
{ Pid::PART_VOLUME, "part_volume", false, "volume", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "volume") },
|
||||
{ Pid::PART_MUTE, "part_mute", false, "mute", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "mute") },
|
||||
{ Pid::PART_PAN, "part_pan", false, "pan", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "pan") },
|
||||
{ Pid::PART_REVERB, "part_reverb", false, "reverb", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "reverb") },
|
||||
|
||||
{ Pid::PART_CHORUS, "part_chorus", false, "chorus", P_TYPE::INT },
|
||||
{ Pid::DURATION, "duration", false, 0, P_TYPE::FRACTION },
|
||||
{ Pid::DURATION_TYPE, "duration_type", false, 0, P_TYPE::TDURATION },
|
||||
{ Pid::ROLE, "role", false, "role", P_TYPE::INT },
|
||||
{ Pid::TRACK, "track", false, 0, P_TYPE::INT },
|
||||
{ Pid::GLISSANDO_STYLE, "glissando_style", true, "glissandoStyle", P_TYPE::GLISSANDO_STYLE },
|
||||
{ Pid::FRET_STRINGS, "fret_strings", false, "strings", P_TYPE::INT },
|
||||
{ Pid::FRET_FRETS, "fret_frets", false, "frets", P_TYPE::INT },
|
||||
{ Pid::FRET_BARRE, "fret_barre", false, "barre", P_TYPE::INT },
|
||||
{ Pid::FRET_OFFSET, "fret_offset", false, "fretOffset", P_TYPE::INT },
|
||||
{ Pid::PART_CHORUS, "part_chorus", false, "chorus", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "chorus") },
|
||||
{ Pid::DURATION, "duration", false, 0, P_TYPE::FRACTION, QT_TRANSLATE_NOOP("propertyName", "duration") },
|
||||
{ Pid::DURATION_TYPE, "duration_type", false, 0, P_TYPE::TDURATION, QT_TRANSLATE_NOOP("propertyName", "duration type") },
|
||||
{ Pid::ROLE, "role", false, "role", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "role") },
|
||||
{ Pid::TRACK, "track", false, 0, P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "track") },
|
||||
{ Pid::GLISSANDO_STYLE, "glissando_style", true, "glissandoStyle", P_TYPE::GLISSANDO_STYLE, QT_TRANSLATE_NOOP("propertyName", "glissando style") },
|
||||
{ Pid::FRET_STRINGS, "fret_strings", false, "strings", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "strings") },
|
||||
{ Pid::FRET_FRETS, "fret_frets", false, "frets", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "frets") },
|
||||
{ Pid::FRET_BARRE, "fret_barre", false, "barre", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "barre") },
|
||||
{ Pid::FRET_OFFSET, "fret_offset", false, "fretOffset", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "fret offset") },
|
||||
|
||||
{ Pid::FRET_NUM_POS, "fret_num_pos", false, "fretNumPos", P_TYPE::INT },
|
||||
{ Pid::SYSTEM_BRACKET, "system_bracket", false, "type", P_TYPE::INT },
|
||||
{ Pid::GAP, "gap", false, 0, P_TYPE::BOOL },
|
||||
{ Pid::AUTOPLACE, "autoplace", false, "autoplace", P_TYPE::BOOL },
|
||||
{ Pid::DASH_LINE_LEN, "dash_line_len", false, "dashLineLength", P_TYPE::REAL },
|
||||
{ Pid::DASH_GAP_LEN, "dash_gap_len", false, "dashGapLength", P_TYPE::REAL },
|
||||
{ Pid::TICK, "tick", false, 0, P_TYPE::INT },
|
||||
{ Pid::PLAYBACK_VOICE1, "playback_voice1", false, "playbackVoice1", P_TYPE::BOOL },
|
||||
{ Pid::PLAYBACK_VOICE2, "playback_voice2", false, "playbackVoice2", P_TYPE::BOOL },
|
||||
{ Pid::PLAYBACK_VOICE3, "playback_voice3", false, "playbackVoice3", P_TYPE::BOOL },
|
||||
{ Pid::FRET_NUM_POS, "fret_num_pos", false, "fretNumPos", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "fret number position") },
|
||||
{ Pid::SYSTEM_BRACKET, "system_bracket", false, "type", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "type") },
|
||||
{ Pid::GAP, "gap", false, 0, P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "gap") },
|
||||
{ Pid::AUTOPLACE, "autoplace", false, "autoplace", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "autoplace") },
|
||||
{ Pid::DASH_LINE_LEN, "dash_line_len", false, "dashLineLength", P_TYPE::REAL, QT_TRANSLATE_NOOP("propertyName", "dash line length") },
|
||||
{ Pid::DASH_GAP_LEN, "dash_gap_len", false, "dashGapLength", P_TYPE::REAL, QT_TRANSLATE_NOOP("propertyName", "dash gap length") },
|
||||
{ Pid::TICK, "tick", false, 0, P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "tick") },
|
||||
{ Pid::PLAYBACK_VOICE1, "playback_voice1", false, "playbackVoice1", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "playback voice 1") },
|
||||
{ Pid::PLAYBACK_VOICE2, "playback_voice2", false, "playbackVoice2", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "playback voice 2") },
|
||||
{ Pid::PLAYBACK_VOICE3, "playback_voice3", false, "playbackVoice3", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "playback voice 3") },
|
||||
|
||||
{ Pid::PLAYBACK_VOICE4, "playback_voice4", false, "playbackVoice4", P_TYPE::BOOL },
|
||||
{ Pid::SYMBOL, "symbol", true, "symbol", P_TYPE::SYMID },
|
||||
{ Pid::PLAY_REPEATS, "play_repeats", true, "playRepeats", P_TYPE::BOOL },
|
||||
{ Pid::CREATE_SYSTEM_HEADER, "create_system_header", false, "createSystemHeader", P_TYPE::BOOL },
|
||||
{ Pid::STAFF_LINES, "staff_lines", true, "lines", P_TYPE::INT },
|
||||
{ Pid::LINE_DISTANCE, "line_distance", true, "lineDistance", P_TYPE::SPATIUM },
|
||||
{ Pid::STEP_OFFSET, "step_offset", true, "stepOffset", P_TYPE::INT },
|
||||
{ Pid::STAFF_SHOW_BARLINES, "staff_show_barlines", false, "", P_TYPE::BOOL },
|
||||
{ Pid::STAFF_SHOW_LEDGERLINES, "staff_show_ledgerlines", false, "", P_TYPE::BOOL },
|
||||
{ Pid::STAFF_SLASH_STYLE, "staff_slash_style", false, "", P_TYPE::BOOL },
|
||||
{ Pid::PLAYBACK_VOICE4, "playback_voice4", false, "playbackVoice4", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "playback voice 4") },
|
||||
{ Pid::SYMBOL, "symbol", true, "symbol", P_TYPE::SYMID, QT_TRANSLATE_NOOP("propertyName", "symbol") },
|
||||
{ Pid::PLAY_REPEATS, "play_repeats", true, "playRepeats", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "playing repeats") },
|
||||
{ Pid::CREATE_SYSTEM_HEADER, "create_system_header", false, "createSystemHeader", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "creating system header") },
|
||||
{ Pid::STAFF_LINES, "staff_lines", true, "lines", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "lines") },
|
||||
{ Pid::LINE_DISTANCE, "line_distance", true, "lineDistance", P_TYPE::SPATIUM, QT_TRANSLATE_NOOP("propertyName", "line distance") },
|
||||
{ Pid::STEP_OFFSET, "step_offset", true, "stepOffset", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "step offset") },
|
||||
{ Pid::STAFF_SHOW_BARLINES, "staff_show_barlines", false, "", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "showing barlines") },
|
||||
{ Pid::STAFF_SHOW_LEDGERLINES, "staff_show_ledgerlines", false, "", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "showing ledgerlines") },
|
||||
{ Pid::STAFF_SLASH_STYLE, "staff_slash_style", false, "", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "slash style") },
|
||||
|
||||
{ Pid::STAFF_NOTEHEAD_SCHEME, "staff_notehead_scheme", false, "", P_TYPE::INT },
|
||||
{ Pid::STAFF_GEN_CLEF, "staff_gen_clef", false, "", P_TYPE::BOOL },
|
||||
{ Pid::STAFF_GEN_TIMESIG, "staff_gen_timesig", false, "", P_TYPE::BOOL },
|
||||
{ Pid::STAFF_GEN_KEYSIG, "staff_gen_keysig", false, "", P_TYPE::BOOL },
|
||||
{ Pid::STAFF_YOFFSET, "staff_yoffset", false, "", P_TYPE::SPATIUM },
|
||||
{ Pid::STAFF_USERDIST, "staff_userdist", false, "distOffset", P_TYPE::SP_REAL },
|
||||
{ Pid::STAFF_BARLINE_SPAN, "staff_barline_span", false, "barLineSpan", P_TYPE::BOOL },
|
||||
{ Pid::STAFF_BARLINE_SPAN_FROM, "staff_barline_span_from", false, "barLineSpanFrom", P_TYPE::INT },
|
||||
{ Pid::STAFF_BARLINE_SPAN_TO, "staff_barline_span_to", false, "barLineSpanTo", P_TYPE::INT },
|
||||
{ Pid::BRACKET_SPAN, "bracket_span", false, "bracketSpan", P_TYPE::INT },
|
||||
{ Pid::STAFF_NOTEHEAD_SCHEME, "staff_notehead_scheme", false, "", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "notehead scheme") },
|
||||
{ Pid::STAFF_GEN_CLEF, "staff_gen_clef", false, "", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "generating clefs") },
|
||||
{ Pid::STAFF_GEN_TIMESIG, "staff_gen_timesig", false, "", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "generating time signature") },
|
||||
{ Pid::STAFF_GEN_KEYSIG, "staff_gen_keysig", false, "", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "generating key signature") },
|
||||
{ Pid::STAFF_YOFFSET, "staff_yoffset", false, "", P_TYPE::SPATIUM, QT_TRANSLATE_NOOP("propertyName", "y-offset") },
|
||||
{ Pid::STAFF_USERDIST, "staff_userdist", false, "distOffset", P_TYPE::SP_REAL, QT_TRANSLATE_NOOP("propertyName", "distance offset") },
|
||||
{ Pid::STAFF_BARLINE_SPAN, "staff_barline_span", false, "barLineSpan", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "barline span") },
|
||||
{ Pid::STAFF_BARLINE_SPAN_FROM, "staff_barline_span_from", false, "barLineSpanFrom", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "barline span from") },
|
||||
{ Pid::STAFF_BARLINE_SPAN_TO, "staff_barline_span_to", false, "barLineSpanTo", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "barline span to") },
|
||||
{ Pid::BRACKET_SPAN, "bracket_span", false, "bracketSpan", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "bracket span") },
|
||||
|
||||
{ Pid::BRACKET_COLUMN, "bracket_column", false, "level", P_TYPE::INT },
|
||||
{ Pid::INAME_LAYOUT_POSITION, "iname_layout_position", false, "layoutPosition", P_TYPE::INT },
|
||||
{ Pid::SUB_STYLE, "sub_style", false, "style", P_TYPE::SUB_STYLE },
|
||||
{ Pid::FONT_FACE, "font_face", false, "family", P_TYPE::FONT },
|
||||
{ Pid::FONT_SIZE, "font_size", false, "size", P_TYPE::REAL },
|
||||
{ Pid::FONT_BOLD, "font_bold", false, "bold", P_TYPE::BOOL },
|
||||
{ Pid::FONT_ITALIC, "font_italic", false, "italic", P_TYPE::BOOL },
|
||||
{ Pid::FONT_UNDERLINE, "font_underline", false, "underline", P_TYPE::BOOL },
|
||||
{ Pid::FRAME_TYPE, "frame_type", false, "frameType", P_TYPE::INT },
|
||||
{ Pid::FRAME_WIDTH, "frame_width", false, "frameWidth", P_TYPE::SPATIUM },
|
||||
{ Pid::BRACKET_COLUMN, "bracket_column", false, "level", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "level") },
|
||||
{ Pid::INAME_LAYOUT_POSITION, "iname_layout_position", false, "layoutPosition", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "layout position") },
|
||||
{ Pid::SUB_STYLE, "sub_style", false, "style", P_TYPE::SUB_STYLE, QT_TRANSLATE_NOOP("propertyName", "style") },
|
||||
{ Pid::FONT_FACE, "font_face", false, "family", P_TYPE::FONT, QT_TRANSLATE_NOOP("propertyName", "family") },
|
||||
{ Pid::FONT_SIZE, "font_size", false, "size", P_TYPE::REAL, QT_TRANSLATE_NOOP("propertyName", "size") },
|
||||
{ Pid::FONT_BOLD, "font_bold", false, "bold", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "bold") },
|
||||
{ Pid::FONT_ITALIC, "font_italic", false, "italic", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "italic") },
|
||||
{ Pid::FONT_UNDERLINE, "font_underline", false, "underline", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "underlined") },
|
||||
{ Pid::FRAME_TYPE, "frame_type", false, "frameType", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "frame type") },
|
||||
{ Pid::FRAME_WIDTH, "frame_width", false, "frameWidth", P_TYPE::SPATIUM, QT_TRANSLATE_NOOP("propertyName", "frame width") },
|
||||
//200
|
||||
{ Pid::FRAME_PADDING, "frame_padding", false, "framePadding", P_TYPE::SPATIUM },
|
||||
{ Pid::FRAME_ROUND, "frame_round", false, "frameRound", P_TYPE::INT },
|
||||
{ Pid::FRAME_FG_COLOR, "frame_fg_color", false, "frameFgColor", P_TYPE::COLOR },
|
||||
{ Pid::FRAME_BG_COLOR, "frame_bg_color", false, "frameBgColor", P_TYPE::COLOR },
|
||||
{ Pid::SIZE_SPATIUM_DEPENDENT, "size_spatium_dependent", false, "sizeIsSpatiumDependent",P_TYPE::BOOL },
|
||||
{ Pid::ALIGN, "align", false, "align", P_TYPE::ALIGN },
|
||||
{ Pid::SYSTEM_FLAG, "system_flag", false, "systemFlag", P_TYPE::BOOL },
|
||||
{ Pid::BEGIN_TEXT, "begin_text", false, "beginText", P_TYPE::STRING },
|
||||
{ Pid::FRAME_PADDING, "frame_padding", false, "framePadding", P_TYPE::SPATIUM, QT_TRANSLATE_NOOP("propertyName", "frame padding") },
|
||||
{ Pid::FRAME_ROUND, "frame_round", false, "frameRound", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "frame round") },
|
||||
{ Pid::FRAME_FG_COLOR, "frame_fg_color", false, "frameFgColor", P_TYPE::COLOR, QT_TRANSLATE_NOOP("propertyName", "frame foreground color") },
|
||||
{ Pid::FRAME_BG_COLOR, "frame_bg_color", false, "frameBgColor", P_TYPE::COLOR, QT_TRANSLATE_NOOP("propertyName", "frame background color") },
|
||||
{ Pid::SIZE_SPATIUM_DEPENDENT, "size_spatium_dependent", false, "sizeIsSpatiumDependent",P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "spatium dependent font") },
|
||||
{ Pid::ALIGN, "align", false, "align", P_TYPE::ALIGN, QT_TRANSLATE_NOOP("propertyName", "align") },
|
||||
{ Pid::SYSTEM_FLAG, "system_flag", false, "systemFlag", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "system flag") },
|
||||
{ Pid::BEGIN_TEXT, "begin_text", false, "beginText", P_TYPE::STRING, QT_TRANSLATE_NOOP("propertyName", "begin text") },
|
||||
|
||||
{ Pid::BEGIN_TEXT_ALIGN, "begin_text_align", false, "beginTextAlign", P_TYPE::ALIGN },
|
||||
{ Pid::BEGIN_TEXT_PLACE, "begin_text_place", false, "beginTextPlace", P_TYPE::TEXT_PLACE },
|
||||
{ Pid::BEGIN_HOOK_TYPE, "begin_hook_type", false, "beginHookType", P_TYPE::INT },
|
||||
{ Pid::BEGIN_HOOK_HEIGHT, "begin_hook_height", false, "beginHookHeight", P_TYPE::SPATIUM },
|
||||
{ Pid::BEGIN_FONT_FACE, "begin_font_face", false, "beginFontFace", P_TYPE::FONT },
|
||||
{ Pid::BEGIN_FONT_SIZE, "begin_font_size", false, "beginFontSize", P_TYPE::REAL },
|
||||
{ Pid::BEGIN_FONT_BOLD, "begin_font_bold", false, "beginFontBold", P_TYPE::BOOL },
|
||||
{ Pid::BEGIN_FONT_ITALIC, "begin_font_italic", false, "beginFontItalic", P_TYPE::BOOL },
|
||||
{ Pid::BEGIN_FONT_UNDERLINE, "begin_font_underline", false, "beginFontUnderline", P_TYPE::BOOL },
|
||||
{ Pid::BEGIN_TEXT_OFFSET, "begin_text_offset", false, "beginTextOffset", P_TYPE::POINT_SP },
|
||||
{ Pid::BEGIN_TEXT_ALIGN, "begin_text_align", false, "beginTextAlign", P_TYPE::ALIGN, QT_TRANSLATE_NOOP("propertyName", "begin text align") },
|
||||
{ Pid::BEGIN_TEXT_PLACE, "begin_text_place", false, "beginTextPlace", P_TYPE::TEXT_PLACE, QT_TRANSLATE_NOOP("propertyName", "begin text place") },
|
||||
{ Pid::BEGIN_HOOK_TYPE, "begin_hook_type", false, "beginHookType", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "begin hook type") },
|
||||
{ Pid::BEGIN_HOOK_HEIGHT, "begin_hook_height", false, "beginHookHeight", P_TYPE::SPATIUM, QT_TRANSLATE_NOOP("propertyName", "begin hook height") },
|
||||
{ Pid::BEGIN_FONT_FACE, "begin_font_face", false, "beginFontFace", P_TYPE::FONT, QT_TRANSLATE_NOOP("propertyName", "begin font face") },
|
||||
{ Pid::BEGIN_FONT_SIZE, "begin_font_size", false, "beginFontSize", P_TYPE::REAL, QT_TRANSLATE_NOOP("propertyName", "begin font size") },
|
||||
{ Pid::BEGIN_FONT_BOLD, "begin_font_bold", false, "beginFontBold", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "begin font bold") },
|
||||
{ Pid::BEGIN_FONT_ITALIC, "begin_font_italic", false, "beginFontItalic", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "begin font italic") },
|
||||
{ Pid::BEGIN_FONT_UNDERLINE, "begin_font_underline", false, "beginFontUnderline", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "begin font underlined") },
|
||||
{ Pid::BEGIN_TEXT_OFFSET, "begin_text_offset", false, "beginTextOffset", P_TYPE::POINT_SP, QT_TRANSLATE_NOOP("propertyName", "begin text offset") },
|
||||
|
||||
{ Pid::CONTINUE_TEXT, "continue_text", false, "continueText", P_TYPE::STRING },
|
||||
{ Pid::CONTINUE_TEXT_ALIGN, "continue_text_align", false, "continueTextAlign", P_TYPE::ALIGN },
|
||||
{ Pid::CONTINUE_TEXT_PLACE, "continue_text_place", false, "continueTextPlace", P_TYPE::TEXT_PLACE },
|
||||
{ Pid::CONTINUE_FONT_FACE, "continue_font_face", false, "continueFontFace", P_TYPE::FONT },
|
||||
{ Pid::CONTINUE_FONT_SIZE, "continue_font_size", false, "continueFontSize", P_TYPE::REAL },
|
||||
{ Pid::CONTINUE_FONT_BOLD, "continue_font_bold", false, "continueFontBold", P_TYPE::BOOL },
|
||||
{ Pid::CONTINUE_FONT_ITALIC, "continue_font_italic", false, "continueFontItalic", P_TYPE::BOOL },
|
||||
{ Pid::CONTINUE_FONT_UNDERLINE, "continue_font_underline", false, "continueFontUnderline", P_TYPE::BOOL },
|
||||
{ Pid::CONTINUE_TEXT_OFFSET, "continue_text_offset", false, "continueTextOffset", P_TYPE::POINT_SP },
|
||||
{ Pid::END_TEXT, "end_text", false, "endText", P_TYPE::STRING },
|
||||
{ Pid::CONTINUE_TEXT, "continue_text", false, "continueText", P_TYPE::STRING, QT_TRANSLATE_NOOP("propertyName", "continue text") },
|
||||
{ Pid::CONTINUE_TEXT_ALIGN, "continue_text_align", false, "continueTextAlign", P_TYPE::ALIGN, QT_TRANSLATE_NOOP("propertyName", "continue text align") },
|
||||
{ Pid::CONTINUE_TEXT_PLACE, "continue_text_place", false, "continueTextPlace", P_TYPE::TEXT_PLACE, QT_TRANSLATE_NOOP("propertyName", "continue text place") },
|
||||
{ Pid::CONTINUE_FONT_FACE, "continue_font_face", false, "continueFontFace", P_TYPE::FONT, QT_TRANSLATE_NOOP("propertyName", "continue font face") },
|
||||
{ Pid::CONTINUE_FONT_SIZE, "continue_font_size", false, "continueFontSize", P_TYPE::REAL, QT_TRANSLATE_NOOP("propertyName", "continue font size") },
|
||||
{ Pid::CONTINUE_FONT_BOLD, "continue_font_bold", false, "continueFontBold", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "continue font bold") },
|
||||
{ Pid::CONTINUE_FONT_ITALIC, "continue_font_italic", false, "continueFontItalic", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "continue font italic") },
|
||||
{ Pid::CONTINUE_FONT_UNDERLINE, "continue_font_underline", false, "continueFontUnderline", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "continue font underlined") },
|
||||
{ Pid::CONTINUE_TEXT_OFFSET, "continue_text_offset", false, "continueTextOffset", P_TYPE::POINT_SP, QT_TRANSLATE_NOOP("propertyName", "continue text offset") },
|
||||
{ Pid::END_TEXT, "end_text", false, "endText", P_TYPE::STRING, QT_TRANSLATE_NOOP("propertyName", "end text") },
|
||||
|
||||
{ Pid::END_TEXT_ALIGN, "end_text_align", false, "endTextAlign", P_TYPE::ALIGN },
|
||||
{ Pid::END_TEXT_PLACE, "end_text_place", false, "endTextPlace", P_TYPE::TEXT_PLACE },
|
||||
{ Pid::END_HOOK_TYPE, "end_hook_type", false, "endHookType", P_TYPE::INT },
|
||||
{ Pid::END_HOOK_HEIGHT, "end_hook_height", false, "endHookHeight", P_TYPE::SPATIUM },
|
||||
{ Pid::END_FONT_FACE, "end_font_face", false, "endFontFace", P_TYPE::FONT },
|
||||
{ Pid::END_FONT_SIZE, "end_font_size", false, "endFontSize", P_TYPE::REAL },
|
||||
{ Pid::END_FONT_BOLD, "end_font_bold", false, "endFontBold", P_TYPE::BOOL },
|
||||
{ Pid::END_FONT_ITALIC, "end_font_italic", false, "endFontItalic", P_TYPE::BOOL },
|
||||
{ Pid::END_FONT_UNDERLINE, "end_font_underline", false, "endFontUnderline", P_TYPE::BOOL },
|
||||
{ Pid::END_TEXT_OFFSET, "end_text_offset", false, "endTextOffset", P_TYPE::POINT_SP },
|
||||
{ Pid::END_TEXT_ALIGN, "end_text_align", false, "endTextAlign", P_TYPE::ALIGN, QT_TRANSLATE_NOOP("propertyName", "end text align") },
|
||||
{ Pid::END_TEXT_PLACE, "end_text_place", false, "endTextPlace", P_TYPE::TEXT_PLACE, QT_TRANSLATE_NOOP("propertyName", "end text place") },
|
||||
{ Pid::END_HOOK_TYPE, "end_hook_type", false, "endHookType", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "end hook type") },
|
||||
{ Pid::END_HOOK_HEIGHT, "end_hook_height", false, "endHookHeight", P_TYPE::SPATIUM, QT_TRANSLATE_NOOP("propertyName", "end hook height") },
|
||||
{ Pid::END_FONT_FACE, "end_font_face", false, "endFontFace", P_TYPE::FONT, QT_TRANSLATE_NOOP("propertyName", "end font face") },
|
||||
{ Pid::END_FONT_SIZE, "end_font_size", false, "endFontSize", P_TYPE::REAL, QT_TRANSLATE_NOOP("propertyName", "end font size") },
|
||||
{ Pid::END_FONT_BOLD, "end_font_bold", false, "endFontBold", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "end font bold") },
|
||||
{ Pid::END_FONT_ITALIC, "end_font_italic", false, "endFontItalic", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "end font italic") },
|
||||
{ Pid::END_FONT_UNDERLINE, "end_font_underline", false, "endFontUnderline", P_TYPE::BOOL, QT_TRANSLATE_NOOP("propertyName", "end font underlined") },
|
||||
{ Pid::END_TEXT_OFFSET, "end_text_offset", false, "endTextOffset", P_TYPE::POINT_SP, QT_TRANSLATE_NOOP("propertyName", "end text offset") },
|
||||
|
||||
{ Pid::POS_ABOVE, "pos_above", false, "posAbove", P_TYPE::SP_REAL },
|
||||
{ Pid::POS_ABOVE, "pos_above", false, "posAbove", P_TYPE::SP_REAL, QT_TRANSLATE_NOOP("propertyName", "position above") },
|
||||
|
||||
{ Pid::END, "++end++", false, "++end++", P_TYPE::INT }
|
||||
{ Pid::LOCATION_STAVES, 0, false, "staves", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "staves distance") },
|
||||
{ Pid::LOCATION_VOICES, 0, false, "voices", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "voices distance") },
|
||||
{ Pid::LOCATION_MEASURES, 0, false, "measures", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "measures distance") },
|
||||
{ Pid::LOCATION_FRACTIONS, 0, false, "fractions", P_TYPE::FRACTION, QT_TRANSLATE_NOOP("propertyName", "position distance") },
|
||||
{ Pid::LOCATION_GRACE, 0, false, "grace", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "grace note index") },
|
||||
{ Pid::LOCATION_NOTE, 0, false, "note", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "note index") },
|
||||
|
||||
{ Pid::VOICE, 0, false, "voice", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "voice") },
|
||||
{ Pid::POSITION, 0, false, "position", P_TYPE::FRACTION, QT_TRANSLATE_NOOP("propertyName", "position") },
|
||||
|
||||
{ Pid::END, "++end++", false, "++end++", P_TYPE::INT, QT_TRANSLATE_NOOP("propertyName", "<invalid property>") }
|
||||
};
|
||||
|
||||
//---------------------------------------------------------
|
||||
// propertyId
|
||||
// propertyIdQml
|
||||
//---------------------------------------------------------
|
||||
|
||||
Pid propertyId(const QString& s)
|
||||
Pid propertyIdQml(const QStringRef& s)
|
||||
{
|
||||
for (const PropertyMetaData& pd : propertyList) {
|
||||
if (pd.qml == s)
|
||||
|
@ -319,6 +330,37 @@ Pid propertyId(const QString& s)
|
|||
return Pid::END;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// propertyIdQml
|
||||
//---------------------------------------------------------
|
||||
|
||||
Pid propertyIdQml(const QString& s)
|
||||
{
|
||||
return propertyIdQml(QStringRef(&s));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// propertyIdName
|
||||
//---------------------------------------------------------
|
||||
|
||||
Pid propertyIdName(const QStringRef& s)
|
||||
{
|
||||
for (const PropertyMetaData& pd : propertyList) {
|
||||
if (pd.name == s)
|
||||
return pd.id;
|
||||
}
|
||||
return Pid::END;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// propertyId
|
||||
//---------------------------------------------------------
|
||||
|
||||
Pid propertyIdName(const QString& s)
|
||||
{
|
||||
return propertyIdName(QStringRef(&s));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// propertyType
|
||||
//---------------------------------------------------------
|
||||
|
@ -355,6 +397,16 @@ const char* propertyQmlName(Pid id)
|
|||
return propertyList[int(id)].qml;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// propertyUserName
|
||||
//---------------------------------------------------------
|
||||
|
||||
QString propertyUserName(Pid id)
|
||||
{
|
||||
Q_ASSERT(propertyList[int(id)].id == id);
|
||||
return QObject::tr(propertyList[int(id)].userName, "propertyName");
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// readProperty
|
||||
//---------------------------------------------------------
|
||||
|
|
|
@ -324,6 +324,16 @@ enum class Pid {
|
|||
|
||||
POS_ABOVE,
|
||||
|
||||
LOCATION_STAVES,
|
||||
LOCATION_VOICES,
|
||||
LOCATION_MEASURES,
|
||||
LOCATION_FRACTIONS,
|
||||
LOCATION_GRACE,
|
||||
LOCATION_NOTE,
|
||||
|
||||
VOICE,
|
||||
POSITION,
|
||||
|
||||
END
|
||||
};
|
||||
|
||||
|
@ -371,7 +381,11 @@ extern P_TYPE propertyType(Pid);
|
|||
extern const char* propertyName(Pid);
|
||||
extern const char* propertyQmlName(Pid);
|
||||
extern bool propertyLink(Pid id);
|
||||
extern Pid propertyId(const QString&);
|
||||
extern Pid propertyIdQml(const QString& qmlName);
|
||||
extern Pid propertyIdQml(const QStringRef& qmlName);
|
||||
extern Pid propertyIdName(const QString& name);
|
||||
extern Pid propertyIdName(const QStringRef& name);
|
||||
extern QString propertyUserName(Pid);
|
||||
|
||||
} // namespace Ms
|
||||
#endif
|
||||
|
|
|
@ -850,7 +850,7 @@ void Rest::write(XmlWriter& xml) const
|
|||
if (_gap)
|
||||
return;
|
||||
writeBeam(xml);
|
||||
xml.stag(name());
|
||||
xml.stag(this);
|
||||
ChordRest::writeProperties(xml);
|
||||
el().write(xml);
|
||||
bool write_dots = false;
|
||||
|
|
|
@ -737,6 +737,15 @@ void Score::setMarkIrregularMeasures(bool v)
|
|||
setUpdateAll();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// readOnly
|
||||
//---------------------------------------------------------
|
||||
|
||||
bool Score::readOnly() const
|
||||
{
|
||||
return _masterScore->readOnly();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// dirty
|
||||
//---------------------------------------------------------
|
||||
|
@ -746,6 +755,15 @@ bool Score::dirty() const
|
|||
return !undoStack()->isClean();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// state
|
||||
//---------------------------------------------------------
|
||||
|
||||
ScoreContentState Score::state() const
|
||||
{
|
||||
return std::make_pair(this, undoStack()->state());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// spell
|
||||
//---------------------------------------------------------
|
||||
|
@ -1611,6 +1629,24 @@ MeasureBase* Score::measure(int idx) const
|
|||
return mb;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// crMeasure
|
||||
// Returns a measure containing chords an rests
|
||||
// by its index skipping other MeasureBase descendants
|
||||
//---------------------------------------------------------
|
||||
|
||||
Measure* Score::crMeasure(int idx) const
|
||||
{
|
||||
int i = -1;
|
||||
for (MeasureBase* mb = _measures.first(); mb; mb = mb->next()) {
|
||||
if (mb->isMeasure())
|
||||
++i;
|
||||
if (i == idx)
|
||||
return toMeasure(mb);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// lastMeasure
|
||||
//---------------------------------------------------------
|
||||
|
|
|
@ -280,6 +280,12 @@ class UpdateState {
|
|||
QList<ScoreElement*> _deleteList;
|
||||
};
|
||||
|
||||
//---------------------------------------------------------
|
||||
// ScoreContentState
|
||||
//---------------------------------------------------------
|
||||
|
||||
typedef std::pair<const Score*, int> ScoreContentState;
|
||||
|
||||
class MasterScore;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -550,6 +556,7 @@ class Score : public QObject, public ScoreElement {
|
|||
Score* clone();
|
||||
|
||||
virtual bool isMaster() const { return false; }
|
||||
virtual bool readOnly() const;
|
||||
|
||||
virtual inline QList<Excerpt*>& excerpts();
|
||||
virtual inline const QList<Excerpt*>& excerpts() const;
|
||||
|
@ -796,6 +803,7 @@ class Score : public QObject, public ScoreElement {
|
|||
void setImportedFilePath(const QString& filePath);
|
||||
|
||||
bool dirty() const;
|
||||
ScoreContentState state() const;
|
||||
void setCreated(bool val) { _created = val; }
|
||||
bool created() const { return _created; }
|
||||
bool savedCapture() const { return _savedCapture; }
|
||||
|
@ -948,6 +956,7 @@ class Score : public QObject, public ScoreElement {
|
|||
Ms::Measure* lastMeasure() const;
|
||||
Ms::Measure* lastMeasureMM() const;
|
||||
MeasureBase* measure(int idx) const;
|
||||
Measure* crMeasure(int idx) const;
|
||||
|
||||
int endTick() const;
|
||||
|
||||
|
@ -1191,6 +1200,8 @@ class MasterScore : public Score {
|
|||
MasterScore* _prev { 0 };
|
||||
Movements* _movements { 0 };
|
||||
|
||||
bool _readOnly { false };
|
||||
|
||||
CmdState _cmdState; // modified during cmd processing
|
||||
|
||||
Omr* _omr { 0 };
|
||||
|
@ -1210,6 +1221,7 @@ class MasterScore : public Score {
|
|||
void removeDeletedMidiMapping();
|
||||
int updateMidiMapping();
|
||||
|
||||
QFileInfo _sessionStartBackupInfo;
|
||||
QFileInfo info;
|
||||
|
||||
bool read(XmlReader&);
|
||||
|
@ -1223,6 +1235,8 @@ class MasterScore : public Score {
|
|||
MasterScore* clone();
|
||||
|
||||
virtual bool isMaster() const override { return true; }
|
||||
virtual bool readOnly() const override { return _readOnly; }
|
||||
void setReadOnly(bool ro) { _readOnly = ro; }
|
||||
virtual UndoStack* undoStack() const override { return _movements->undo(); }
|
||||
virtual TimeSigMap* sigmap() const override { return _sigmap; }
|
||||
virtual TempoMap* tempomap() const override { return _tempomap; }
|
||||
|
@ -1296,6 +1310,8 @@ class MasterScore : public Score {
|
|||
const QFileInfo* fileInfo() const { return &info; }
|
||||
void setName(const QString&);
|
||||
|
||||
const QFileInfo& sessionStartBackupInfo() const { return _sessionStartBackupInfo; }
|
||||
|
||||
virtual QString title() const override;
|
||||
|
||||
virtual int pageIdx(Page* page) const override { return movements()->pageIdx(page); }
|
||||
|
|
|
@ -417,6 +417,34 @@ void ScoreElement::writeProperty(XmlWriter& xml, Pid id) const
|
|||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// propertyId
|
||||
//---------------------------------------------------------
|
||||
|
||||
Pid ScoreElement::propertyId(const QStringRef& xmlName) const
|
||||
{
|
||||
return propertyIdName(xmlName);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// propertyUserValue
|
||||
//---------------------------------------------------------
|
||||
|
||||
QString ScoreElement::propertyUserValue(Pid id) const
|
||||
{
|
||||
QVariant val = getProperty(id);
|
||||
switch (propertyType(id)) {
|
||||
case P_TYPE::POINT_SP:
|
||||
{
|
||||
QPointF p = val.toPointF();
|
||||
return QString("(%1, %2)").arg(p.x()).arg(p.y());
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return val.toString();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// readStyledProperty
|
||||
//---------------------------------------------------------
|
||||
|
@ -689,13 +717,14 @@ QString ScoreElement::userName() const
|
|||
// name2type
|
||||
//---------------------------------------------------------
|
||||
|
||||
ElementType ScoreElement::name2type(const QStringRef& s)
|
||||
ElementType ScoreElement::name2type(const QStringRef& s, bool silent)
|
||||
{
|
||||
for (int i = 0; i < int(ElementType::MAXTYPE); ++i) {
|
||||
if (s == elementNames[i].name)
|
||||
return ElementType(i);
|
||||
}
|
||||
qDebug("unknown type <%s>", qPrintable(s.toString()));
|
||||
if (!silent)
|
||||
qDebug("unknown type <%s>", qPrintable(s.toString()));
|
||||
return ElementType::INVALID;
|
||||
}
|
||||
|
||||
|
|
|
@ -191,7 +191,7 @@ class ScoreElement {
|
|||
virtual QString userName() const;
|
||||
virtual ElementType type() const = 0;
|
||||
|
||||
static ElementType name2type(const QStringRef&);
|
||||
static ElementType name2type(const QStringRef&, bool silent = false);
|
||||
static const char* name(ElementType);
|
||||
|
||||
virtual QVariant getProperty(Pid) const = 0;
|
||||
|
@ -203,6 +203,9 @@ class ScoreElement {
|
|||
|
||||
virtual void reset(); // reset all properties & position to default
|
||||
|
||||
virtual Pid propertyId(const QStringRef& xmlName) const;
|
||||
virtual QString propertyUserValue(Pid) const;
|
||||
|
||||
virtual void initElementStyle(const ElementStyle*);
|
||||
virtual const ElementStyle* styledProperties() const { return _elementStyle; }
|
||||
|
||||
|
@ -342,10 +345,13 @@ class ScoreElement {
|
|||
CONVERT(StaffText, STAFF_TEXT)
|
||||
CONVERT(SystemText, SYSTEM_TEXT)
|
||||
CONVERT(BracketItem, BRACKET_ITEM)
|
||||
CONVERT(Score, SCORE)
|
||||
CONVERT(Staff, STAFF)
|
||||
CONVERT(Part, PART)
|
||||
CONVERT(BagpipeEmbellishment, BAGPIPE_EMBELLISHMENT)
|
||||
#undef CONVERT
|
||||
|
||||
virtual bool isElement() const { return false; } // overriden in element.h
|
||||
bool isChordRest() const { return isRest() || isChord() || isRepeatMeasure(); }
|
||||
bool isDurationElement() const { return isChordRest() || isTuplet(); }
|
||||
bool isSlurTieSegment() const { return isSlurSegment() || isTieSegment(); }
|
||||
|
@ -491,6 +497,7 @@ static inline const StaffTextBase* toStaffTextBase(const ScoreElement* e) {
|
|||
static inline a* to##a(ScoreElement* e) { Q_ASSERT(e == 0 || e->is##a()); return (a*)e; } \
|
||||
static inline const a* to##a(const ScoreElement* e) { Q_ASSERT(e == 0 || e->is##a()); return (const a*)e; }
|
||||
|
||||
CONVERT(Element)
|
||||
CONVERT(Note)
|
||||
CONVERT(Chord)
|
||||
CONVERT(BarLine)
|
||||
|
@ -580,7 +587,9 @@ static inline const a* to##a(const ScoreElement* e) { Q_ASSERT(e == 0 || e->is##
|
|||
CONVERT(Page)
|
||||
CONVERT(SystemText)
|
||||
CONVERT(BracketItem)
|
||||
CONVERT(Score)
|
||||
CONVERT(Staff)
|
||||
CONVERT(Part)
|
||||
CONVERT(BagpipeEmbellishment)
|
||||
#undef CONVERT
|
||||
|
||||
|
|
1432
libmscore/scorediff.cpp
Normal file
1432
libmscore/scorediff.cpp
Normal file
File diff suppressed because it is too large
Load diff
170
libmscore/scorediff.h
Normal file
170
libmscore/scorediff.h
Normal file
|
@ -0,0 +1,170 @@
|
|||
//=============================================================================
|
||||
// MuseScore
|
||||
// Music Composition & Notation
|
||||
//
|
||||
// Copyright (C) 2018 Werner Schweer
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2
|
||||
// as published by the Free Software Foundation and appearing in
|
||||
// the file LICENCE.GPL
|
||||
//=============================================================================
|
||||
|
||||
#ifndef __SCOREDIFF_H__
|
||||
#define __SCOREDIFF_H__
|
||||
|
||||
#include "score.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace Ms {
|
||||
|
||||
enum class Pid;
|
||||
class ScoreElement;
|
||||
|
||||
//---------------------------------------------------------
|
||||
// ItemType
|
||||
//---------------------------------------------------------
|
||||
|
||||
enum class ItemType {
|
||||
ELEMENT,
|
||||
PROPERTY,
|
||||
MARKUP,
|
||||
CONTEXTCHANGE
|
||||
};
|
||||
|
||||
//---------------------------------------------------------
|
||||
// DiffType
|
||||
//---------------------------------------------------------
|
||||
|
||||
enum class DiffType {
|
||||
EQUAL,
|
||||
INSERT,
|
||||
DELETE,
|
||||
REPLACE
|
||||
};
|
||||
|
||||
//---------------------------------------------------------
|
||||
// TextDiff
|
||||
// A structure similar to Diff from diff_match_patch
|
||||
// but contains info on line numbers of the diff
|
||||
//---------------------------------------------------------
|
||||
|
||||
struct TextDiff {
|
||||
DiffType type;
|
||||
QString text[2];
|
||||
int start[2]; // starting line numbers in both texts
|
||||
int end[2]; // ending line numbers in both texts
|
||||
|
||||
void merge(const TextDiff& other); // merge other diff into this one
|
||||
QString toString(DiffType type, bool prefixLines = false) const;
|
||||
QString toString(bool prefixLines = false) const { return toString(type, prefixLines); }
|
||||
};
|
||||
|
||||
//---------------------------------------------------------
|
||||
// BaseDiff
|
||||
//---------------------------------------------------------
|
||||
|
||||
struct BaseDiff {
|
||||
DiffType type;
|
||||
const TextDiff* textDiff;
|
||||
const ScoreElement* ctx[2];
|
||||
const ScoreElement* before[2];
|
||||
|
||||
virtual ~BaseDiff() = default;
|
||||
|
||||
virtual ItemType itemType() const = 0;
|
||||
virtual bool sameItem(const BaseDiff&) const;
|
||||
virtual Fraction afrac(int score) const;
|
||||
virtual QString toString() const = 0;
|
||||
};
|
||||
|
||||
//---------------------------------------------------------
|
||||
// ContextChange
|
||||
// Dummy Diff for temporary storing information on
|
||||
// context changes.
|
||||
//---------------------------------------------------------
|
||||
|
||||
struct ContextChange : public BaseDiff {
|
||||
ItemType itemType() const override { return ItemType::CONTEXTCHANGE; }
|
||||
QString toString() const override;
|
||||
};
|
||||
|
||||
//---------------------------------------------------------
|
||||
// ElementDiff
|
||||
//---------------------------------------------------------
|
||||
|
||||
struct ElementDiff : public BaseDiff {
|
||||
const ScoreElement* el[2];
|
||||
|
||||
ItemType itemType() const override { return ItemType::ELEMENT; }
|
||||
bool sameItem(const BaseDiff&) const override;
|
||||
Fraction afrac(int score) const override;
|
||||
QString toString() const override;
|
||||
};
|
||||
|
||||
//---------------------------------------------------------
|
||||
// PropertyDiff
|
||||
//---------------------------------------------------------
|
||||
|
||||
struct PropertyDiff : public BaseDiff {
|
||||
Pid pid;
|
||||
|
||||
ItemType itemType() const override { return ItemType::PROPERTY; }
|
||||
bool sameItem(const BaseDiff&) const override;
|
||||
QString toString() const override;
|
||||
};
|
||||
|
||||
//---------------------------------------------------------
|
||||
// MarkupDiff
|
||||
//---------------------------------------------------------
|
||||
|
||||
struct MarkupDiff : public BaseDiff {
|
||||
QString name;
|
||||
QVariant info;
|
||||
|
||||
ItemType itemType() const override { return ItemType::MARKUP; }
|
||||
bool sameItem(const BaseDiff&) const override;
|
||||
QString toString() const override;
|
||||
};
|
||||
|
||||
//---------------------------------------------------------
|
||||
// ScoreDiff
|
||||
//---------------------------------------------------------
|
||||
|
||||
class ScoreDiff {
|
||||
std::vector<TextDiff> _textDiffs; // raw diff between MSCX code for scores
|
||||
std::vector<const TextDiff*> _mergedTextDiffs; // extra diff items created after merging score diff items
|
||||
std::vector<BaseDiff*> _diffs;
|
||||
Score* _s1;
|
||||
Score* _s2;
|
||||
ScoreContentState _scoreState1;
|
||||
ScoreContentState _scoreState2;
|
||||
|
||||
bool _textDiffOnly;
|
||||
|
||||
void processMarkupDiffs();
|
||||
void mergeInsertDeleteDiffs();
|
||||
void mergeElementDiffs();
|
||||
void editPropertyDiffs();
|
||||
|
||||
public:
|
||||
ScoreDiff(Score* s1, Score* s2, bool textDiffOnly = false);
|
||||
ScoreDiff(const ScoreDiff&) = delete;
|
||||
~ScoreDiff();
|
||||
|
||||
void update();
|
||||
bool updated() const { return _scoreState1 == _s1->state() && _scoreState2 == _s2->state(); }
|
||||
|
||||
std::vector<BaseDiff*>& diffs() { return _diffs; }
|
||||
const std::vector<TextDiff>& textDiffs() const { return _textDiffs; }
|
||||
|
||||
const Score* score1() const { return _s1; }
|
||||
const Score* score2() const { return _s2; }
|
||||
|
||||
QString rawDiff(bool skipEqual = true) const;
|
||||
QString userDiff() const;
|
||||
};
|
||||
|
||||
} // namespace Ms
|
||||
#endif
|
|
@ -102,7 +102,7 @@ void Score::writeMovement(XmlWriter& xml, bool selectionOnly)
|
|||
p->setShow(false);
|
||||
}
|
||||
|
||||
xml.stag("Score");
|
||||
xml.stag(this);
|
||||
if (excerpt()) {
|
||||
Excerpt* e = excerpt();
|
||||
QMultiMap<int, int> trackList = e->tracks();
|
||||
|
@ -208,7 +208,7 @@ void Score::writeMovement(XmlWriter& xml, bool selectionOnly)
|
|||
xml.setTrackDiff(-staffStart * VOICES);
|
||||
if (measureStart) {
|
||||
for (int staffIdx = staffStart; staffIdx < staffEnd; ++staffIdx) {
|
||||
xml.stag(QString("Staff id=\"%1\"").arg(staffIdx + 1 - staffStart));
|
||||
xml.stag(staff(staffIdx), QString("id=\"%1\"").arg(staffIdx + 1 - staffStart));
|
||||
xml.setCurTick(measureStart->tick());
|
||||
xml.setTickDiff(xml.curTick());
|
||||
xml.setCurTrack(staffIdx * VOICES);
|
||||
|
@ -372,6 +372,8 @@ void Score::readStaff(XmlReader& e)
|
|||
|
||||
bool MasterScore::saveFile()
|
||||
{
|
||||
if (readOnly())
|
||||
return false;
|
||||
QString suffix = info.suffix();
|
||||
if (info.exists() && !info.isWritable()) {
|
||||
MScore::lastError = tr("The following file is locked: \n%1 \n\nTry saving to a different location.").arg(info.filePath());
|
||||
|
@ -431,8 +433,11 @@ bool MasterScore::saveFile()
|
|||
// tr("Renaming old file <%1> to backup <%2> failed").arg(name, backupname);
|
||||
}
|
||||
}
|
||||
#ifdef Q_OS_WIN
|
||||
|
||||
QFileInfo fileBackup(dir, backupName);
|
||||
_sessionStartBackupInfo = fileBackup;
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
QString backupNativePath = QDir::toNativeSeparators(fileBackup.absoluteFilePath());
|
||||
#if (defined (_MSCVER) || defined (_MSC_VER))
|
||||
#if (defined (UNICODE))
|
||||
|
@ -482,6 +487,8 @@ bool MasterScore::saveFile()
|
|||
|
||||
bool Score::saveCompressedFile(QFileInfo& info, bool onlySelection)
|
||||
{
|
||||
if (readOnly() && info == *masterScore()->fileInfo())
|
||||
return false;
|
||||
QFile fp(info.filePath());
|
||||
if (!fp.open(QIODevice::WriteOnly)) {
|
||||
MScore::lastError = tr("Open File\n%1\nfailed: %2").arg(info.filePath(), strerror(errno));
|
||||
|
@ -627,6 +634,8 @@ bool Score::saveCompressedFile(QIODevice* f, QFileInfo& info, bool onlySelection
|
|||
|
||||
bool Score::saveFile(QFileInfo& info)
|
||||
{
|
||||
if (readOnly() && info == *masterScore()->fileInfo())
|
||||
return false;
|
||||
if (info.suffix().isEmpty())
|
||||
info.setFile(info.filePath() + ".mscx");
|
||||
QFile fp(info.filePath());
|
||||
|
|
|
@ -808,7 +808,7 @@ void Segment::write(XmlWriter& xml) const
|
|||
setWritten(true);
|
||||
if (_extraLeadingSpace.isZero())
|
||||
return;
|
||||
xml.stag(name());
|
||||
xml.stag(this);
|
||||
xml.tag("leadingSpace", _extraLeadingSpace.val());
|
||||
xml.etag();
|
||||
}
|
||||
|
|
|
@ -1003,7 +1003,7 @@ void Slur::write(XmlWriter& xml) const
|
|||
}
|
||||
if (!xml.canWrite(this))
|
||||
return;
|
||||
xml.stag(name());
|
||||
xml.stag(this);
|
||||
SlurTie::writeProperties(xml);
|
||||
xml.etag();
|
||||
}
|
||||
|
|
|
@ -283,7 +283,7 @@ void SlurTieSegment::writeSlur(XmlWriter& xml, int no) const
|
|||
if (autoplace() && visible() && (color() == Qt::black))
|
||||
return;
|
||||
|
||||
xml.stag(QString("%1 no=\"%2\"").arg(name()).arg(no));
|
||||
xml.stag(this, QString("no=\"%1\"").arg(no));
|
||||
|
||||
qreal _spatium = spatium();
|
||||
xml.tag("o1", ups(Grip::START).off / _spatium);
|
||||
|
|
|
@ -176,7 +176,7 @@ void Spacer::updateGrips(EditData& ed) const
|
|||
|
||||
void Spacer::write(XmlWriter& xml) const
|
||||
{
|
||||
xml.stag(name());
|
||||
xml.stag(this);
|
||||
xml.tag("subtype", int(_spacerType));
|
||||
Element::writeProperties(xml);
|
||||
xml.tag("space", _gap / spatium());
|
||||
|
|
|
@ -437,6 +437,16 @@ QVariant Spanner::getProperty(Pid propertyId) const
|
|||
return track2();
|
||||
case Pid::ANCHOR:
|
||||
return int(anchor());
|
||||
case Pid::LOCATION_STAVES:
|
||||
return (track2() / VOICES) - (track() / VOICES);
|
||||
case Pid::LOCATION_VOICES:
|
||||
return (track2() % VOICES) - (track() / VOICES);
|
||||
case Pid::LOCATION_FRACTIONS:
|
||||
return Fraction::fromTicks(_ticks);
|
||||
case Pid::LOCATION_MEASURES:
|
||||
case Pid::LOCATION_GRACE:
|
||||
case Pid::LOCATION_NOTE:
|
||||
return Location::getLocationProperty(propertyId, startElement(), endElement());
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -576,7 +576,7 @@ int Staff::currentKeyTick(int tick) const
|
|||
void Staff::write(XmlWriter& xml) const
|
||||
{
|
||||
int idx = this->idx();
|
||||
xml.stag(QString("Staff id=\"%1\"").arg(idx + 1));
|
||||
xml.stag(this, QString("id=\"%1\"").arg(idx + 1));
|
||||
if (links()) {
|
||||
Score* s = masterScore();
|
||||
for (auto le : *links()) {
|
||||
|
|
|
@ -49,7 +49,7 @@ StaffState::~StaffState()
|
|||
|
||||
void StaffState::write(XmlWriter& xml) const
|
||||
{
|
||||
xml.stag(name());
|
||||
xml.stag(this);
|
||||
xml.tag("subtype", int(_staffStateType));
|
||||
if (staffStateType() == StaffStateType::INSTRUMENT)
|
||||
_instrument->write(xml, nullptr);
|
||||
|
|
|
@ -37,7 +37,7 @@ void StaffTextBase::write(XmlWriter& xml) const
|
|||
{
|
||||
if (!xml.canWrite(this))
|
||||
return;
|
||||
xml.stag(name());
|
||||
xml.stag(this);
|
||||
|
||||
for (ChannelActions s : _channelActions) {
|
||||
int channel = s.channel;
|
||||
|
|
|
@ -42,7 +42,7 @@ StaffTypeChange::StaffTypeChange(const StaffTypeChange& lb)
|
|||
|
||||
void StaffTypeChange::write(XmlWriter& xml) const
|
||||
{
|
||||
xml.stag(name());
|
||||
xml.stag(this);
|
||||
if (_staffType)
|
||||
_staffType->write(xml);
|
||||
Element::writeProperties(xml);
|
||||
|
|
|
@ -212,7 +212,7 @@ void Stem::draw(QPainter* painter) const
|
|||
|
||||
void Stem::write(XmlWriter& xml) const
|
||||
{
|
||||
xml.stag("Stem");
|
||||
xml.stag(this);
|
||||
Element::writeProperties(xml);
|
||||
writeProperty(xml, Pid::USER_LEN);
|
||||
writeProperty(xml, Pid::LINE_WIDTH);
|
||||
|
|
|
@ -97,7 +97,7 @@ void Symbol::draw(QPainter* p) const
|
|||
|
||||
void Symbol::write(XmlWriter& xml) const
|
||||
{
|
||||
xml.stag(name());
|
||||
xml.stag(this);
|
||||
xml.tag("name", Sym::id2name(_sym));
|
||||
if (_scoreFont)
|
||||
xml.tag("font", _scoreFont->name());
|
||||
|
@ -199,7 +199,7 @@ void FSymbol::draw(QPainter* painter) const
|
|||
|
||||
void FSymbol::write(XmlWriter& xml) const
|
||||
{
|
||||
xml.stag(name());
|
||||
xml.stag(this);
|
||||
xml.tag("font", _font.family());
|
||||
xml.tag("fontsize", _font.pointSizeF());
|
||||
xml.tag("code", _code);
|
||||
|
|
|
@ -984,7 +984,7 @@ qreal System::staffCanvasYpage(int staffIdx) const
|
|||
|
||||
void System::write(XmlWriter& xml) const
|
||||
{
|
||||
xml.stag("System");
|
||||
xml.stag(this);
|
||||
if (_systemDividerLeft && _systemDividerLeft->isUserModified())
|
||||
_systemDividerLeft->write(xml);
|
||||
if (_systemDividerRight && _systemDividerRight->isUserModified())
|
||||
|
|
|
@ -87,9 +87,9 @@ QRectF SystemDivider::drag(EditData& ed)
|
|||
void SystemDivider::write(XmlWriter& xml) const
|
||||
{
|
||||
if (dividerType() == SystemDivider::Type::LEFT)
|
||||
xml.stag(QString("SystemDivider type=\"left\""));
|
||||
xml.stag(this, "type=\"left\"");
|
||||
else
|
||||
xml.stag(QString("SystemDivider type=\"right\""));
|
||||
xml.stag(this, "type=\"right\"");
|
||||
writeProperties(xml);
|
||||
xml.etag();
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ TempoText::TempoText(Score* s)
|
|||
|
||||
void TempoText::write(XmlWriter& xml) const
|
||||
{
|
||||
xml.stag(name());
|
||||
xml.stag(this);
|
||||
xml.tag("tempo", _tempo);
|
||||
if (_followText)
|
||||
xml.tag("followText", _followText);
|
||||
|
|
|
@ -1649,7 +1649,7 @@ void TextBase::write(XmlWriter& xml) const
|
|||
{
|
||||
if (!xml.canWrite(this))
|
||||
return;
|
||||
xml.stag(name());
|
||||
xml.stag(this);
|
||||
writeProperties(xml, true, true);
|
||||
xml.etag();
|
||||
}
|
||||
|
@ -1687,28 +1687,28 @@ void TextBase::writeProperties(XmlWriter& xml, bool writeText, bool /*writeStyle
|
|||
xml.writeXml("text", xmlText());
|
||||
}
|
||||
|
||||
static constexpr std::array<Pid, 18> pids { {
|
||||
Pid::SUB_STYLE,
|
||||
Pid::FONT_FACE,
|
||||
Pid::FONT_SIZE,
|
||||
Pid::FONT_BOLD,
|
||||
Pid::FONT_ITALIC,
|
||||
Pid::FONT_UNDERLINE,
|
||||
Pid::FRAME_TYPE,
|
||||
Pid::FRAME_WIDTH,
|
||||
Pid::FRAME_PADDING,
|
||||
Pid::FRAME_ROUND,
|
||||
Pid::FRAME_FG_COLOR,
|
||||
Pid::FRAME_BG_COLOR,
|
||||
Pid::ALIGN,
|
||||
} };
|
||||
|
||||
//---------------------------------------------------------
|
||||
// readProperties
|
||||
//---------------------------------------------------------
|
||||
|
||||
bool TextBase::readProperties(XmlReader& e)
|
||||
{
|
||||
static const std::array<Pid, 18> pids { {
|
||||
Pid::SUB_STYLE,
|
||||
Pid::FONT_FACE,
|
||||
Pid::FONT_SIZE,
|
||||
Pid::FONT_BOLD,
|
||||
Pid::FONT_ITALIC,
|
||||
Pid::FONT_UNDERLINE,
|
||||
Pid::FRAME_TYPE,
|
||||
Pid::FRAME_WIDTH,
|
||||
Pid::FRAME_PADDING,
|
||||
Pid::FRAME_ROUND,
|
||||
Pid::FRAME_FG_COLOR,
|
||||
Pid::FRAME_BG_COLOR,
|
||||
Pid::ALIGN,
|
||||
} };
|
||||
|
||||
const QStringRef& tag(e.name());
|
||||
for (Pid i :pids) {
|
||||
if (readProperty(tag, e, i))
|
||||
|
@ -1721,6 +1721,21 @@ bool TextBase::readProperties(XmlReader& e)
|
|||
return true;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// propertyId
|
||||
//---------------------------------------------------------
|
||||
|
||||
Pid TextBase::propertyId(const QStringRef& name) const
|
||||
{
|
||||
if (name == "text")
|
||||
return Pid::TEXT;
|
||||
for (Pid pid : pids) {
|
||||
if (propertyName(pid) == name)
|
||||
return pid;
|
||||
}
|
||||
return Element::propertyId(name);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// pageRectangle
|
||||
//---------------------------------------------------------
|
||||
|
|
|
@ -335,6 +335,7 @@ class TextBase : public Element {
|
|||
virtual QVariant getProperty(Pid propertyId) const override;
|
||||
virtual bool setProperty(Pid propertyId, const QVariant& v) override;
|
||||
virtual QVariant propertyDefault(Pid id) const override;
|
||||
virtual Pid propertyId(const QStringRef& xmlName) const override;
|
||||
virtual Sid getPropertyStyle(Pid) const;
|
||||
virtual void styleChanged();
|
||||
|
||||
|
|
|
@ -91,7 +91,7 @@ void TBox::layout()
|
|||
|
||||
void TBox::write(XmlWriter& xml) const
|
||||
{
|
||||
xml.stag(name());
|
||||
xml.stag(this);
|
||||
Box::writeProperties(xml);
|
||||
_text->write(xml);
|
||||
xml.etag();
|
||||
|
|
|
@ -395,7 +395,7 @@ void TextLineBase::write(XmlWriter& xml) const
|
|||
{
|
||||
if (!xml.canWrite(this))
|
||||
return;
|
||||
xml.stag(name());
|
||||
xml.stag(this);
|
||||
writeProperties(xml);
|
||||
xml.etag();
|
||||
}
|
||||
|
@ -454,6 +454,19 @@ bool TextLineBase::readProperties(XmlReader& e)
|
|||
return SLine::readProperties(e);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// TextLineBase::propertyId
|
||||
//---------------------------------------------------------
|
||||
|
||||
Pid TextLineBase::propertyId(const QStringRef& name) const
|
||||
{
|
||||
for (Pid pid : pids) {
|
||||
if (propertyName(pid) == name)
|
||||
return pid;
|
||||
}
|
||||
return SLine::propertyId(name);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// getProperty
|
||||
//---------------------------------------------------------
|
||||
|
|
|
@ -121,6 +121,7 @@ class TextLineBase : public SLine {
|
|||
|
||||
virtual QVariant getProperty(Pid id) const override;
|
||||
virtual bool setProperty(Pid propertyId, const QVariant&) override;
|
||||
virtual Pid propertyId(const QStringRef& xmlName) const override;
|
||||
};
|
||||
|
||||
} // namespace Ms
|
||||
|
|
|
@ -519,7 +519,7 @@ Tie::Tie(Score* s)
|
|||
|
||||
void Tie::write(XmlWriter& xml) const
|
||||
{
|
||||
xml.stag(name());
|
||||
xml.stag(this);
|
||||
SlurTie::writeProperties(xml);
|
||||
xml.etag();
|
||||
}
|
||||
|
|
|
@ -125,7 +125,7 @@ void TimeSig::setDenominatorString(const QString& a)
|
|||
|
||||
void TimeSig::write(XmlWriter& xml) const
|
||||
{
|
||||
xml.stag("TimeSig");
|
||||
xml.stag(this);
|
||||
writeProperty(xml, Pid::TIMESIG_TYPE);
|
||||
Element::writeProperties(xml);
|
||||
|
||||
|
@ -217,6 +217,23 @@ void TimeSig::read(XmlReader& e)
|
|||
_stretch.reduce();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// propertyId
|
||||
//---------------------------------------------------------
|
||||
|
||||
Pid TimeSig::propertyId(const QStringRef& name) const
|
||||
{
|
||||
if (name == "subtype")
|
||||
return Pid::TIMESIG_TYPE;
|
||||
if (name == "sigN" || name == "sigD")
|
||||
return Pid::TIMESIG;
|
||||
if (name == "stretchN" || name == "stretchD")
|
||||
return Pid::TIMESIG_STRETCH;
|
||||
if (name == "Groups")
|
||||
return Pid::GROUPS;
|
||||
return Element::propertyId(name);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// layout
|
||||
//---------------------------------------------------------
|
||||
|
|
|
@ -112,6 +112,7 @@ class TimeSig final : public Element {
|
|||
virtual QVariant getProperty(Pid propertyId) const override;
|
||||
virtual bool setProperty(Pid propertyId, const QVariant&) override;
|
||||
virtual QVariant propertyDefault(Pid id) const override;
|
||||
virtual Pid propertyId(const QStringRef& xmlName) const override;
|
||||
|
||||
const Groups& groups() const { return _groups; }
|
||||
void setGroups(const Groups& e) { _groups = e; }
|
||||
|
|
|
@ -358,7 +358,7 @@ void Tremolo::write(XmlWriter& xml) const
|
|||
{
|
||||
if (!xml.canWrite(this))
|
||||
return;
|
||||
xml.stag(name());
|
||||
xml.stag(this);
|
||||
xml.tag("subtype", tremoloTypeName());
|
||||
Element::writeProperties(xml);
|
||||
xml.etag();
|
||||
|
|
|
@ -86,7 +86,7 @@ void TremoloBar::draw(QPainter* painter) const
|
|||
|
||||
void TremoloBar::write(XmlWriter& xml) const
|
||||
{
|
||||
xml.stag("TremoloBar");
|
||||
xml.stag(this);
|
||||
writeProperty(xml, Pid::MAG);
|
||||
writeProperty(xml, Pid::LINE_WIDTH);
|
||||
writeProperty(xml, Pid::PLAY);
|
||||
|
|
|
@ -307,7 +307,7 @@ void Trill::write(XmlWriter& xml) const
|
|||
{
|
||||
if (!xml.canWrite(this))
|
||||
return;
|
||||
xml.stag(name());
|
||||
xml.stag(this);
|
||||
xml.tag("subtype", trillTypeName());
|
||||
writeProperty(xml, Pid::PLAY);
|
||||
writeProperty(xml, Pid::ORNAMENT_STYLE);
|
||||
|
|
|
@ -707,7 +707,7 @@ void Tuplet::scanElements(void* data, void (*func)(void*, Element*), bool all)
|
|||
|
||||
void Tuplet::write(XmlWriter& xml) const
|
||||
{
|
||||
xml.stag(name());
|
||||
xml.stag(this);
|
||||
Element::writeProperties(xml);
|
||||
|
||||
writeProperty(xml, Pid::DIRECTION);
|
||||
|
@ -722,7 +722,7 @@ void Tuplet::write(XmlWriter& xml) const
|
|||
xml.tag("baseNote", _baseLen.name());
|
||||
|
||||
if (_number) {
|
||||
xml.stag("Number");
|
||||
xml.stag("Number", _number);
|
||||
_number->writeProperties(xml);
|
||||
xml.etag();
|
||||
}
|
||||
|
|
|
@ -186,7 +186,9 @@ UndoStack::UndoStack()
|
|||
{
|
||||
curCmd = 0;
|
||||
curIdx = 0;
|
||||
cleanIdx = 0;
|
||||
cleanState = 0;
|
||||
stateList.push_back(cleanState);
|
||||
nextState = 1;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
@ -267,17 +269,18 @@ void UndoStack::remove(int idx)
|
|||
// remove redo stack
|
||||
while (list.size() > curIdx) {
|
||||
UndoCommand* cmd = list.takeLast();
|
||||
stateList.pop_back();
|
||||
cmd->cleanup(false); // delete elements for which UndoCommand() holds ownership
|
||||
delete cmd;
|
||||
// --curIdx;
|
||||
}
|
||||
while (list.size() > idx) {
|
||||
UndoCommand* cmd = list.takeLast();
|
||||
stateList.pop_back();
|
||||
cmd->cleanup(true);
|
||||
delete cmd;
|
||||
}
|
||||
curIdx = idx;
|
||||
// TODO: handle cleanIdx
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
@ -325,10 +328,12 @@ void UndoStack::endMacro(bool rollback)
|
|||
// remove redo stack
|
||||
while (list.size() > curIdx) {
|
||||
UndoCommand* cmd = list.takeLast();
|
||||
stateList.pop_back();
|
||||
cmd->cleanup(false); // delete elements for which UndoCommand() holds ownership
|
||||
delete cmd;
|
||||
}
|
||||
list.append(curCmd);
|
||||
stateList.push_back(nextState++);
|
||||
++curIdx;
|
||||
}
|
||||
curCmd = 0;
|
||||
|
@ -345,6 +350,7 @@ void UndoStack::reopen()
|
|||
Q_ASSERT(curIdx > 0);
|
||||
--curIdx;
|
||||
curCmd = list.takeAt(curIdx);
|
||||
stateList.erase(stateList.begin() + curIdx);
|
||||
for (auto i : curCmd->commands()) {
|
||||
qDebug(" <%s>", i->name());
|
||||
}
|
||||
|
@ -356,7 +362,7 @@ void UndoStack::reopen()
|
|||
|
||||
void UndoStack::setClean()
|
||||
{
|
||||
cleanIdx = curIdx;
|
||||
cleanState = state();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
|
|
@ -119,8 +119,10 @@ class UndoCommand {
|
|||
class UndoStack {
|
||||
UndoCommand* curCmd;
|
||||
QList<UndoCommand*> list;
|
||||
std::vector<int> stateList;
|
||||
int nextState;
|
||||
int cleanState;
|
||||
int curIdx;
|
||||
int cleanIdx;
|
||||
|
||||
public:
|
||||
UndoStack();
|
||||
|
@ -135,7 +137,8 @@ class UndoStack {
|
|||
void setClean();
|
||||
bool canUndo() const { return curIdx > 0; }
|
||||
bool canRedo() const { return curIdx < list.size(); }
|
||||
bool isClean() const { return cleanIdx == curIdx; }
|
||||
int state() const { return stateList[curIdx]; }
|
||||
bool isClean() const { return cleanState == state(); }
|
||||
int getCurIdx() const { return curIdx; }
|
||||
void remove(int idx);
|
||||
bool empty() const { return !canUndo() && !canRedo(); }
|
||||
|
|
|
@ -196,7 +196,7 @@ void Vibrato::write(XmlWriter& xml) const
|
|||
{
|
||||
if (!xml.canWrite(this))
|
||||
return;
|
||||
xml.stag(name());
|
||||
xml.stag(this);
|
||||
xml.tag("subtype", vibratoTypeName());
|
||||
writeProperty(xml, Pid::PLAY);
|
||||
SLine::writeProperties(xml);
|
||||
|
|
|
@ -151,7 +151,7 @@ void Volta::read(XmlReader& e)
|
|||
|
||||
void Volta::write(XmlWriter& xml) const
|
||||
{
|
||||
xml.stag(name());
|
||||
xml.stag(this);
|
||||
TextLineBase::writeProperties(xml);
|
||||
QString s;
|
||||
for (int i : _endings) {
|
||||
|
|
|
@ -216,12 +216,17 @@ class XmlWriter : public QTextStream {
|
|||
bool _clipboardmode = { false }; // used to modify write() behaviour
|
||||
bool _excerptmode = { false }; // true when writing a part
|
||||
bool _writeOmr = { true }; // false if writing into *.msc file
|
||||
bool _writeTrack = { false };
|
||||
bool _writePosition = { false };
|
||||
int _tupletId = { 1 };
|
||||
int _beamId = { 1 };
|
||||
|
||||
LinksIndexer _linksIndexer;
|
||||
QMap<int, int> _lidLocalIndices;
|
||||
|
||||
std::vector<std::pair<const ScoreElement*, QString>> _elements;
|
||||
bool _recordElements = false;
|
||||
|
||||
void putLevel();
|
||||
|
||||
public:
|
||||
|
@ -238,12 +243,16 @@ class XmlWriter : public QTextStream {
|
|||
bool clipboardmode() const { return _clipboardmode; }
|
||||
bool excerptmode() const { return _excerptmode; }
|
||||
bool writeOmr() const { return _writeOmr; }
|
||||
bool writeTrack() const { return _writeTrack; }
|
||||
bool writePosition() const { return _writePosition; }
|
||||
int nextTupletId() { return _tupletId++; }
|
||||
int nextBeamId() { return _beamId++; }
|
||||
|
||||
void setClipboardmode(bool v) { _clipboardmode = v; }
|
||||
void setExcerptmode(bool v) { _excerptmode = v; }
|
||||
void setWriteOmr(bool v) { _writeOmr = v; }
|
||||
void setWriteTrack(bool v) { _writeTrack= v; }
|
||||
void setWritePosition(bool v) { _writePosition = v; }
|
||||
void setTupletId(int v) { _tupletId = v; }
|
||||
void setBeamId(int v) { _beamId = v; }
|
||||
void setSpannerId(int v) { _spannerId = v; }
|
||||
|
@ -262,6 +271,9 @@ class XmlWriter : public QTextStream {
|
|||
void setLidLocalIndex(int lid, int localIndex) { _lidLocalIndices.insert(lid, localIndex); }
|
||||
int lidLocalIndex(int lid) const { return _lidLocalIndices[lid]; }
|
||||
|
||||
const std::vector<std::pair<const ScoreElement*, QString>>& elements() const { return _elements; }
|
||||
void setRecordElements(bool record) { _recordElements = record; }
|
||||
|
||||
void sTag(const char* name, Spatium sp) { XmlWriter::tag(name, QVariant(sp.val())); }
|
||||
void pTag(const char* name, PlaceText);
|
||||
|
||||
|
@ -270,6 +282,9 @@ class XmlWriter : public QTextStream {
|
|||
void stag(const QString&);
|
||||
void etag();
|
||||
|
||||
void stag(const ScoreElement* se, const QString& attributes = QString());
|
||||
void stag(const QString& name, const ScoreElement* se, const QString& attributes = QString());
|
||||
|
||||
void tagE(const QString&);
|
||||
void tagE(const char* format, ...);
|
||||
void ntag(const char* name);
|
||||
|
|
|
@ -93,6 +93,34 @@ void XmlWriter::stag(const QString& s)
|
|||
stack.append(s.split(' ')[0]);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// stag
|
||||
// <mops attribute="value">
|
||||
//---------------------------------------------------------
|
||||
|
||||
void XmlWriter::stag(const ScoreElement* se, const QString& attributes)
|
||||
{
|
||||
stag(se->name(), se, attributes);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// stag
|
||||
// <mops attribute="value">
|
||||
//---------------------------------------------------------
|
||||
|
||||
void XmlWriter::stag(const QString& name, const ScoreElement* se, const QString& attributes)
|
||||
{
|
||||
putLevel();
|
||||
*this << '<' << name;
|
||||
if (!attributes.isEmpty())
|
||||
*this << ' ' << attributes;
|
||||
*this << '>' << endl;
|
||||
stack.append(name);
|
||||
|
||||
if (_recordElements)
|
||||
_elements.emplace_back(se, name);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// etag
|
||||
// </mops>
|
||||
|
@ -182,6 +210,7 @@ void XmlWriter::tag(Pid id, QVariant data, QVariant defaultData)
|
|||
case P_TYPE::STRING:
|
||||
case P_TYPE::FONT:
|
||||
case P_TYPE::ALIGN:
|
||||
case P_TYPE::FRACTION:
|
||||
tag(name, data);
|
||||
break;
|
||||
case P_TYPE::ORNAMENT_STYLE:
|
||||
|
@ -289,8 +318,6 @@ void XmlWriter::tag(Pid id, QVariant data, QVariant defaultData)
|
|||
case P_TYPE::SUB_STYLE:
|
||||
tag(name, textStyleName(Tid(data.toInt())));
|
||||
break;
|
||||
case P_TYPE::FRACTION:
|
||||
qFatal("unknown: FRACTION");
|
||||
case P_TYPE::POINT_MM:
|
||||
qFatal("unknown: POINT_MM");
|
||||
case P_TYPE::SIZE_MM:
|
||||
|
|
|
@ -56,6 +56,8 @@ QT5_WRAP_UI (ui_headers
|
|||
|
||||
importmidi/importmidi_panel.ui
|
||||
|
||||
scorecmp/scorecmp_tool.ui
|
||||
|
||||
debugger/barline.ui
|
||||
debugger/harmony.ui
|
||||
debugger/box.ui
|
||||
|
@ -412,6 +414,7 @@ add_executable ( ${ExecutableName}
|
|||
importmidi/importmidi_voice.cpp importmidi/importmidi_view.cpp importmidi/importmidi_key.cpp
|
||||
importmidi/importmidi_tempo.cpp importmidi/importmidi_instrument.cpp
|
||||
importmidi/importmidi_chordname.cpp
|
||||
scorecmp/scorecmp.cpp scorecmp/scorediffmodel.cpp scorecmp/scorelistmodel.cpp
|
||||
resourceManager.cpp downloadUtils.cpp
|
||||
textcursor.cpp continuouspanel.cpp accessibletoolbutton.cpp scoreaccessibility.cpp
|
||||
startcenter.cpp scoreBrowser.cpp scorePreview.cpp scoreInfo.cpp
|
||||
|
|
|
@ -74,6 +74,7 @@
|
|||
#include "synthesizer/msynthesizer.h"
|
||||
#include "svggenerator.h"
|
||||
#include "scorePreview.h"
|
||||
#include "scorecmp/scorecmp.h"
|
||||
#include "extension.h"
|
||||
|
||||
#ifdef OMR
|
||||
|
@ -272,7 +273,7 @@ bool MuseScore::checkDirty(MasterScore* s)
|
|||
Handles the GUI's file-open action.
|
||||
*/
|
||||
|
||||
void MuseScore::loadFiles()
|
||||
void MuseScore::loadFiles(bool switchTab, bool singleFile)
|
||||
{
|
||||
QStringList files = getOpenScoreNames(
|
||||
#ifdef OMR
|
||||
|
@ -292,17 +293,18 @@ void MuseScore::loadFiles()
|
|||
tr("Overture / Score Writer Files <experimental>") + " (*.ove *.scw);;" +
|
||||
tr("Bagpipe Music Writer Files <experimental>") + " (*.bww);;" +
|
||||
tr("Guitar Pro") + " (*.gtp *.gp3 *.gp4 *.gp5 *.gpx)",
|
||||
tr("Load Score")
|
||||
tr("Load Score"),
|
||||
singleFile
|
||||
);
|
||||
for (const QString& s : files)
|
||||
openScore(s);
|
||||
openScore(s, switchTab);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// openScore
|
||||
//---------------------------------------------------------
|
||||
|
||||
Score* MuseScore::openScore(const QString& fn)
|
||||
Score* MuseScore::openScore(const QString& fn, bool switchTab)
|
||||
{
|
||||
//
|
||||
// make sure we load a file only once
|
||||
|
@ -317,7 +319,9 @@ Score* MuseScore::openScore(const QString& fn)
|
|||
MasterScore* score = readScore(fn);
|
||||
if (score) {
|
||||
score->updateCapo();
|
||||
setCurrentScoreView(appendScore(score));
|
||||
const int tabIdx = appendScore(score);
|
||||
if (switchTab)
|
||||
setCurrentScoreView(tabIdx);
|
||||
writeSessionFile(false);
|
||||
}
|
||||
return score;
|
||||
|
@ -435,6 +439,7 @@ bool MuseScore::saveFile(MasterScore* score)
|
|||
}
|
||||
score->setCreated(false);
|
||||
updateWindowTitle(score);
|
||||
scoreCmpTool->updateScoreVersions(score);
|
||||
int idx = scoreList.indexOf(score->masterScore());
|
||||
tab1->setTabText(idx, score->fileInfo()->completeBaseName());
|
||||
if (tab2)
|
||||
|
@ -781,6 +786,61 @@ void MuseScore::newFile()
|
|||
setCurrentScoreView(appendScore(score));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// copy
|
||||
// Copy content of src file do dest file overwriting it.
|
||||
// Implemented manually as QFile::copy refuses to
|
||||
// overwrite existing files.
|
||||
//---------------------------------------------------------
|
||||
|
||||
static bool copy(QFile& src, QFile& dest)
|
||||
{
|
||||
src.open(QIODevice::ReadOnly);
|
||||
dest.open(QIODevice::WriteOnly);
|
||||
constexpr qint64 size = 1024 * 1024;
|
||||
char* buf = new char[size];
|
||||
bool err = false;
|
||||
while (qint64 r = src.read(buf, size)) {
|
||||
if (r < 0) {
|
||||
err = true;
|
||||
break;
|
||||
}
|
||||
qint64 w = dest.write(buf, r);
|
||||
if (w < r) {
|
||||
err = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
dest.close();
|
||||
src.close();
|
||||
delete[] buf;
|
||||
return !err;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// getTemporaryScoreFileCopy
|
||||
// baseNameTemplate is the template to be passed to
|
||||
// QTemporaryFile constructor but without suffix and
|
||||
// directory --- they are defined automatically.
|
||||
//---------------------------------------------------------
|
||||
|
||||
QTemporaryFile* MuseScore::getTemporaryScoreFileCopy(const QFileInfo& info, const QString& baseNameTemplate)
|
||||
{
|
||||
QString suffix(info.suffix());
|
||||
if (suffix.endsWith(",")) // some backup files created by MuseScore
|
||||
suffix.chop(1);
|
||||
QTemporaryFile* f = new QTemporaryFile(
|
||||
QDir::temp().absoluteFilePath(baseNameTemplate + '.' + suffix),
|
||||
this
|
||||
);
|
||||
QFile src(info.absoluteFilePath());
|
||||
if (!copy(src, *f)) {
|
||||
delete f;
|
||||
return nullptr;
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// addScorePreview
|
||||
// add a score preview to the file dialog
|
||||
|
@ -815,7 +875,7 @@ static QList<QUrl> sidebarUrls()
|
|||
// getOpenScoreNames
|
||||
//---------------------------------------------------------
|
||||
|
||||
QStringList MuseScore::getOpenScoreNames(const QString& filter, const QString& title)
|
||||
QStringList MuseScore::getOpenScoreNames(const QString& filter, const QString& title, bool singleFile)
|
||||
{
|
||||
QSettings set;
|
||||
QString dir = set.value("lastOpenPath", preferences.getString(PREF_APP_PATHS_MYSCORES)).toString();
|
||||
|
@ -834,7 +894,7 @@ QStringList MuseScore::getOpenScoreNames(const QString& filter, const QString& t
|
|||
|
||||
if (loadScoreDialog == 0) {
|
||||
loadScoreDialog = new QFileDialog(this);
|
||||
loadScoreDialog->setFileMode(QFileDialog::ExistingFiles);
|
||||
loadScoreDialog->setFileMode(singleFile ? QFileDialog::ExistingFile : QFileDialog::ExistingFiles);
|
||||
loadScoreDialog->setOption(QFileDialog::DontUseNativeDialog, true);
|
||||
loadScoreDialog->setWindowTitle(title);
|
||||
addScorePreview(loadScoreDialog);
|
||||
|
@ -1879,6 +1939,7 @@ bool MuseScore::saveAs(Score* cs_, bool saveCopy, const QString& path, const QSt
|
|||
cs_->undoStack()->setClean();
|
||||
dirtyChanged(cs_);
|
||||
cs_->setCreated(false);
|
||||
scoreCmpTool->updateScoreVersions(cs_);
|
||||
addRecentScore(cs_);
|
||||
writeSessionFile(false);
|
||||
}
|
||||
|
|
|
@ -58,6 +58,8 @@
|
|||
#include "timeline.h"
|
||||
#include "importmidi/importmidi_panel.h"
|
||||
#include "importmidi/importmidi_operations.h"
|
||||
#include "scorecmp/scorecmp.h"
|
||||
#include "libmscore/scorediff.h"
|
||||
#include "libmscore/chord.h"
|
||||
#include "libmscore/segment.h"
|
||||
#include "editraster.h"
|
||||
|
@ -152,6 +154,8 @@ QString dataPath;
|
|||
QString iconPath;
|
||||
|
||||
bool converterMode = false;
|
||||
static bool rawDiffMode = false;
|
||||
static bool diffMode = false;
|
||||
bool processJob = false;
|
||||
bool externalIcons = false;
|
||||
bool pluginMode = false;
|
||||
|
@ -1085,6 +1089,17 @@ MuseScore::MuseScore()
|
|||
scorePageLayoutChanged();
|
||||
showTimeline(false);
|
||||
|
||||
scoreCmpTool = new ScoreComparisonTool;
|
||||
scoreCmpTool->setVisible(false);
|
||||
{
|
||||
QAction* a = getAction("toggle-scorecmp-tool");
|
||||
connect(
|
||||
scoreCmpTool, &ScoreComparisonTool::visibilityChanged,
|
||||
a, &QAction::setChecked
|
||||
);
|
||||
}
|
||||
addDockWidget(Qt::BottomDockWidgetArea, scoreCmpTool);
|
||||
|
||||
mainWindow->setStretchFactor(0, 1);
|
||||
mainWindow->setStretchFactor(1, 0);
|
||||
mainWindow->setSizes(QList<int>({500, 50}));
|
||||
|
@ -1118,19 +1133,11 @@ MuseScore::MuseScore()
|
|||
envelope->setSizes(QList<int>({550, 180}));
|
||||
|
||||
splitter = new QSplitter;
|
||||
tab1 = new ScoreTab(&scoreList, this);
|
||||
tab1->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
connect(tab1, SIGNAL(currentScoreViewChanged(ScoreView*)), SLOT(setCurrentScoreView(ScoreView*)));
|
||||
connect(tab1, SIGNAL(tabCloseRequested(int)), SLOT(removeTab(int)));
|
||||
connect(tab1, SIGNAL(actionTriggered(QAction*)), SLOT(cmd(QAction*)));
|
||||
tab1 = createScoreTab();
|
||||
splitter->addWidget(tab1);
|
||||
|
||||
if (splitScreen()) {
|
||||
tab2 = new ScoreTab(&scoreList, this);
|
||||
tab2->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
connect(tab2, SIGNAL(currentScoreViewChanged(ScoreView*)), SLOT(setCurrentScoreView(ScoreView*)));
|
||||
connect(tab2, SIGNAL(tabCloseRequested(int)), SLOT(removeTab(int)));
|
||||
connect(tab2, SIGNAL(actionTriggered(QAction*)), SLOT(cmd(QAction*)));
|
||||
tab2 = createScoreTab();
|
||||
splitter->addWidget(tab2);
|
||||
tab2->setVisible(false);
|
||||
}
|
||||
|
@ -1370,6 +1377,10 @@ MuseScore::MuseScore()
|
|||
a->setCheckable(true);
|
||||
menuView->addAction(a);
|
||||
|
||||
a = getAction("toggle-scorecmp-tool");
|
||||
a->setCheckable(true);
|
||||
menuView->addAction(a);
|
||||
|
||||
menuView->addSeparator();
|
||||
menuView->addAction(getAction("zoomin"));
|
||||
menuView->addAction(getAction("zoomout"));
|
||||
|
@ -2100,15 +2111,9 @@ int MuseScore::appendScore(MasterScore* score)
|
|||
}
|
||||
}
|
||||
scoreList.insert(index, score);
|
||||
tab1->blockSignals(true);
|
||||
if (tab2)
|
||||
tab2->blockSignals(true);
|
||||
tab1->insertTab(score);
|
||||
if (tab2)
|
||||
tab2->insertTab(score);
|
||||
tab1->blockSignals(false);
|
||||
if (tab2)
|
||||
tab2->blockSignals(false);
|
||||
return index;
|
||||
}
|
||||
|
||||
|
@ -2375,6 +2380,30 @@ void MuseScore::setCurrentScoreView(ScoreView* view)
|
|||
ScoreAccessibility::instance()->updateAccessibilityInfo();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// setCurrentScores
|
||||
//---------------------------------------------------------
|
||||
|
||||
void MuseScore::setCurrentScores(Score* s1, Score* s2)
|
||||
{
|
||||
if (s1)
|
||||
tab1->setCurrentScore(s1);
|
||||
if (s2) {
|
||||
setSplitScreen(true);
|
||||
tab2->setCurrentScore(s2);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// setSplitScreen
|
||||
//---------------------------------------------------------
|
||||
|
||||
void MuseScore::setSplitScreen(bool val)
|
||||
{
|
||||
if (splitScreen() != val)
|
||||
splitWindow(_horizontalSplit);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// updateViewModeCombo
|
||||
//---------------------------------------------------------
|
||||
|
@ -2853,15 +2882,9 @@ void MuseScore::removeTab(int i)
|
|||
midiPanelOnCloseFile(score->importedFilePath());
|
||||
scoreList.removeAt(i);
|
||||
|
||||
tab1->blockSignals(true);
|
||||
tab1->removeTab(i);
|
||||
tab1->blockSignals(false);
|
||||
|
||||
if (tab2) {
|
||||
tab2->blockSignals(true);
|
||||
tab2->removeTab(i);
|
||||
tab2->blockSignals(false);
|
||||
}
|
||||
tab1->removeTab(i, /* noCurrentChangedSignals */ true);
|
||||
if (tab2)
|
||||
tab2->removeTab(i, /* noCurrentChangedSignals */ true);
|
||||
|
||||
cs = 0;
|
||||
cv = 0;
|
||||
|
@ -3318,6 +3341,7 @@ static bool processNonGui(const QStringList& argv)
|
|||
else
|
||||
return convert(argv[0], outFileName);
|
||||
}
|
||||
|
||||
if (!extensionName.isEmpty()) {
|
||||
QFileInfo fi(extensionName);
|
||||
QString suffix = fi.suffix().toLower();
|
||||
|
@ -3328,6 +3352,25 @@ static bool processNonGui(const QStringList& argv)
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (rawDiffMode || diffMode) {
|
||||
if (argv.size() != 2)
|
||||
return false;
|
||||
MasterScore* s1 = mscore->readScore(argv[0]);
|
||||
MasterScore* s2 = mscore->readScore(argv[1]);
|
||||
if (!s1 || !s2)
|
||||
return false;
|
||||
ScoreDiff diff(s1, s2, /* textDiffOnly */ !diffMode);
|
||||
|
||||
if (rawDiffMode)
|
||||
QTextStream(stdout) << diff.rawDiff() << endl;
|
||||
if (diffMode)
|
||||
QTextStream(stdout) << diff.userDiff() << endl;
|
||||
|
||||
delete s1;
|
||||
delete s2;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -4694,11 +4737,7 @@ void MuseScore::splitWindow(bool horizontal)
|
|||
{
|
||||
if (!_splitScreen) {
|
||||
if (tab2 == 0) {
|
||||
tab2 = new ScoreTab(&scoreList, this);
|
||||
tab2->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
connect(tab2, SIGNAL(currentScoreViewChanged(ScoreView*)), SLOT(setCurrentScoreView(ScoreView*)));
|
||||
connect(tab2, SIGNAL(tabCloseRequested(int)), SLOT(removeTab(int)));
|
||||
connect(tab2, SIGNAL(actionTriggered(QAction*)), SLOT(cmd(QAction*)));
|
||||
tab2 = createScoreTab();
|
||||
splitter->addWidget(tab2);
|
||||
}
|
||||
tab2->setVisible(true);
|
||||
|
@ -4712,24 +4751,22 @@ void MuseScore::splitWindow(bool horizontal)
|
|||
s->update();
|
||||
setCurrentView(1, 0);
|
||||
}
|
||||
emit windowSplit(true);
|
||||
}
|
||||
else {
|
||||
if (_horizontalSplit == horizontal) {
|
||||
_splitScreen = false;
|
||||
tab2->setVisible(false);
|
||||
setCurrentView(0, tab1->currentIndex());
|
||||
emit windowSplit(false);
|
||||
}
|
||||
else {
|
||||
_horizontalSplit = horizontal;
|
||||
QAction* a;
|
||||
if (_horizontalSplit)
|
||||
a = getAction("split-v");
|
||||
else
|
||||
a = getAction("split-h");
|
||||
a->setChecked(false);
|
||||
splitter->setOrientation(_horizontalSplit ? Qt::Horizontal : Qt::Vertical);
|
||||
}
|
||||
}
|
||||
getAction("split-h")->setChecked(_splitScreen && _horizontalSplit);
|
||||
getAction("split-v")->setChecked(_splitScreen && !_horizontalSplit);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
@ -5309,6 +5346,7 @@ void MuseScore::endCmd()
|
|||
updateInputState(cs);
|
||||
updateUndoRedo();
|
||||
dirtyChanged(cs);
|
||||
scoreCmpTool->updateDiff();
|
||||
Element* e = cs->selection().element();
|
||||
|
||||
// For multiple notes selected check if they all have same pitch and tuning
|
||||
|
@ -5412,6 +5450,20 @@ void MuseScore::setPlayRepeats(bool repeat)
|
|||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// createScoreTab
|
||||
//---------------------------------------------------------
|
||||
|
||||
ScoreTab* MuseScore::createScoreTab()
|
||||
{
|
||||
ScoreTab* tab = new ScoreTab(&scoreList, this);
|
||||
tab->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
connect(tab, SIGNAL(currentScoreViewChanged(ScoreView*)), SLOT(setCurrentScoreView(ScoreView*)));
|
||||
connect(tab, SIGNAL(tabCloseRequested(int)), SLOT(removeTab(int)));
|
||||
connect(tab, SIGNAL(actionTriggered(QAction*)), SLOT(cmd(QAction*)));
|
||||
return tab;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// cmd
|
||||
//---------------------------------------------------------
|
||||
|
@ -5589,6 +5641,8 @@ void MuseScore::cmd(QAction* a, const QString& cmd)
|
|||
;
|
||||
else if (cmd == "toggle-piano")
|
||||
showPianoKeyboard(a->isChecked());
|
||||
else if (cmd == "toggle-scorecmp-tool")
|
||||
scoreCmpTool->setVisible(a->isChecked());
|
||||
else if (cmd == "plugin-creator")
|
||||
showPluginCreator(a);
|
||||
else if (cmd == "plugin-manager")
|
||||
|
@ -6589,6 +6643,8 @@ int main(int argc, char* av[])
|
|||
parser.addOption(QCommandLineOption({"f", "force"}, "Used with '-o <file>', ignore warnings reg. score being corrupted or from wrong version"));
|
||||
parser.addOption(QCommandLineOption({"b", "bitrate"}, "Used with '-o <file>.mp3', sets bitrate, in kbps", "bitrate"));
|
||||
parser.addOption(QCommandLineOption({"E", "install-extension"}, "Install an extension, load soundfont as default unless if -e is passed too", "extension file"));
|
||||
parser.addOption(QCommandLineOption("raw-diff", "Print a raw diff for the given scores"));
|
||||
parser.addOption(QCommandLineOption("diff", "Print a diff for the given scores"));
|
||||
|
||||
parser.addPositionalArgument("scorefiles", "The files to open", "[scorefile...]");
|
||||
|
||||
|
@ -6726,6 +6782,14 @@ int main(int argc, char* av[])
|
|||
else
|
||||
fprintf(stderr, "MP3 bitrate value '%s' not recognized, using default setting from preferences instead.\n", qPrintable(temp));
|
||||
}
|
||||
if (parser.isSet("raw-diff")) {
|
||||
MScore::noGui = true;
|
||||
rawDiffMode = true;
|
||||
}
|
||||
if (parser.isSet("diff")) {
|
||||
MScore::noGui = true;
|
||||
diffMode = true;
|
||||
}
|
||||
|
||||
QStringList argv = parser.positionalArguments();
|
||||
|
||||
|
@ -6750,6 +6814,10 @@ int main(int argc, char* av[])
|
|||
if (app->sendMessage(QString("")))
|
||||
return 0;
|
||||
}
|
||||
if (rawDiffMode || diffMode) {
|
||||
if (argv.size() != 2)
|
||||
qFatal("Only two scores are needed for performing a comparison");
|
||||
}
|
||||
|
||||
if (dataPath.isEmpty())
|
||||
dataPath = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
|
||||
|
|
|
@ -97,6 +97,7 @@ class SynthesizerState;
|
|||
class Driver;
|
||||
class Seq;
|
||||
class ImportMidiPanel;
|
||||
class ScoreComparisonTool;
|
||||
class Startcenter;
|
||||
class HelpBrowser;
|
||||
class ToolbarEditor;
|
||||
|
@ -243,6 +244,8 @@ class MuseScore : public QMainWindow, public MuseScoreCore {
|
|||
QFrame* importmidiShowPanel;
|
||||
QSplitter* mainWindow;
|
||||
|
||||
ScoreComparisonTool* scoreCmpTool { 0 };
|
||||
|
||||
MagBox* mag;
|
||||
QComboBox* viewModeCombo;
|
||||
QAction* playId;
|
||||
|
@ -467,8 +470,13 @@ class MuseScore : public QMainWindow, public MuseScoreCore {
|
|||
void switchLayoutMode(LayoutMode);
|
||||
void setPlayRepeats(bool repeat);
|
||||
|
||||
ScoreTab* createScoreTab();
|
||||
|
||||
QString getUtmParameters(QString medium) const;
|
||||
|
||||
signals:
|
||||
void windowSplit(bool);
|
||||
|
||||
private slots:
|
||||
void cmd(QAction* a, const QString& cmd);
|
||||
void autoSaveTimerTimeout();
|
||||
|
@ -532,6 +540,7 @@ class MuseScore : public QMainWindow, public MuseScoreCore {
|
|||
void handleMessage(const QString& message);
|
||||
void setCurrentScoreView(ScoreView*);
|
||||
void setCurrentScoreView(int);
|
||||
void setCurrentScores(Score* s1, Score* s2 = nullptr);
|
||||
void setNormalState() { changeState(STATE_NORMAL); }
|
||||
void setPlayState() { changeState(STATE_PLAY); }
|
||||
void setNoteEntryState() { changeState(STATE_NOTE_ENTRY); }
|
||||
|
@ -600,6 +609,7 @@ class MuseScore : public QMainWindow, public MuseScoreCore {
|
|||
void writeSessionFile(bool);
|
||||
bool restoreSession(bool);
|
||||
bool splitScreen() const { return _splitScreen; }
|
||||
void setSplitScreen(bool val);
|
||||
virtual void setCurrentView(int tabIdx, int idx);
|
||||
void loadPlugins();
|
||||
void unloadPlugins();
|
||||
|
@ -617,8 +627,9 @@ class MuseScore : public QMainWindow, public MuseScoreCore {
|
|||
MasterScore* getNewFile();
|
||||
Q_INVOKABLE void loadFile(const QString& url);
|
||||
void loadFile(const QUrl&);
|
||||
QTemporaryFile* getTemporaryScoreFileCopy(const QFileInfo& info, const QString& baseNameTemplate);
|
||||
QNetworkAccessManager* networkManager();
|
||||
virtual Score* openScore(const QString& fn);
|
||||
virtual Score* openScore(const QString& fn, bool switchTab = true);
|
||||
bool hasToCheckForUpdate();
|
||||
bool hasToCheckForExtensionsUpdate();
|
||||
static bool unstable();
|
||||
|
@ -632,7 +643,7 @@ class MuseScore : public QMainWindow, public MuseScoreCore {
|
|||
ScoreTab* getTab2() const { return tab2; }
|
||||
QList<LanguageItem>& languages() { return _languages; }
|
||||
|
||||
QStringList getOpenScoreNames(const QString& filter, const QString& title);
|
||||
QStringList getOpenScoreNames(const QString& filter, const QString& title, bool singleFile = false);
|
||||
QString getSaveScoreName(const QString& title, QString& name, const QString& filter, bool folder = false);
|
||||
QString getStyleFilename(bool open, const QString& title = QString());
|
||||
QString getFotoFilename(QString& filter, QString *selectedFilter);
|
||||
|
@ -704,7 +715,7 @@ class MuseScore : public QMainWindow, public MuseScoreCore {
|
|||
bool countIn() const { return countInAction->isChecked(); }
|
||||
bool panDuringPlayback() const { return panAction->isChecked(); }
|
||||
void noteTooShortForTupletDialog();
|
||||
void loadFiles();
|
||||
void loadFiles(bool switchTab = true, bool singleFile = false);
|
||||
// midi panel functions
|
||||
void midiPanelOnSwitchToFile(const QString &file);
|
||||
void midiPanelOnCloseFile(const QString &file);
|
||||
|
|
518
mscore/scorecmp/scorecmp.cpp
Normal file
518
mscore/scorecmp/scorecmp.cpp
Normal file
|
@ -0,0 +1,518 @@
|
|||
//=============================================================================
|
||||
// MuseScore
|
||||
// Music Composition & Notation
|
||||
//
|
||||
// Copyright (C) 2018 Werner Schweer
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2
|
||||
// as published by the Free Software Foundation and appearing in
|
||||
// the file LICENCE.GPL
|
||||
//=============================================================================
|
||||
|
||||
#include "scorecmp.h"
|
||||
|
||||
#include "ui_scorecmp_tool.h"
|
||||
#include "scorediffmodel.h"
|
||||
#include "scorelistmodel.h"
|
||||
|
||||
#include "musescore.h"
|
||||
#include "scoretab.h"
|
||||
#include "scoreview.h"
|
||||
|
||||
#include "libmscore/scorediff.h"
|
||||
|
||||
namespace Ms {
|
||||
|
||||
//---------------------------------------------------------
|
||||
// ScoreComparisonTool
|
||||
//---------------------------------------------------------
|
||||
|
||||
ScoreComparisonTool::ScoreComparisonTool(QWidget* parent)
|
||||
: QDockWidget(parent), _ui(new Ui::ScoreComparisonTool)
|
||||
{
|
||||
_ui->setupUi(this);
|
||||
_mode = Mode::INTELLIGENT;
|
||||
_ui->intelligentModeRadioButton->setChecked(true);
|
||||
_ui->diffWidget->setCurrentWidget(_ui->pageIntelligentDiff);
|
||||
connect(
|
||||
_ui->score1ComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||||
this, &ScoreComparisonTool::selectedVersionsChanged);
|
||||
connect(
|
||||
_ui->score2ComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||||
this, &ScoreComparisonTool::selectedVersionsChanged);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// ~ScoreComparisonTool
|
||||
//---------------------------------------------------------
|
||||
|
||||
ScoreComparisonTool::~ScoreComparisonTool()
|
||||
{
|
||||
delete _ui;
|
||||
delete _diff;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// ScoreComparisonTool::changeEvent
|
||||
//---------------------------------------------------------
|
||||
|
||||
void ScoreComparisonTool::changeEvent(QEvent* e)
|
||||
{
|
||||
QDockWidget::changeEvent(e);
|
||||
switch(e->type()) {
|
||||
case QEvent::LanguageChange:
|
||||
_ui->retranslateUi(this);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// ScoreComparisonTool::showEvent
|
||||
//---------------------------------------------------------
|
||||
|
||||
void ScoreComparisonTool::showEvent(QShowEvent* e)
|
||||
{
|
||||
QDockWidget::showEvent(e);
|
||||
if (e->spontaneous())
|
||||
return;
|
||||
e->accept();
|
||||
|
||||
if (!_scoreListModel) {
|
||||
ScoreTab* tab = mscore->getTab1();
|
||||
_scoreListModel = new ScoreListModel(&mscore->scores(), tab, this);
|
||||
_ui->score1ComboBox->setModel(_scoreListModel);
|
||||
_ui->score2ComboBox->setModel(_scoreListModel);
|
||||
|
||||
MasterScore* s = nullptr;
|
||||
if (ScoreView* v = tab->view())
|
||||
s = v->score()->masterScore();
|
||||
_scoreVersionsModel1 = new ScoreVersionListModel(s, this);
|
||||
_scoreVersionsModel2 = new ScoreVersionListModel(s, this);
|
||||
_ui->version1ComboBox->setModel(_scoreVersionsModel1);
|
||||
_ui->version2ComboBox->setModel(_scoreVersionsModel2);
|
||||
selectedVersionsChanged();
|
||||
|
||||
_ui->score1ComboBox->setCurrentIndex(tab->currentIndex());
|
||||
connect(tab->getTab(), &QTabBar::currentChanged,
|
||||
_ui->score1ComboBox, &QComboBox::setCurrentIndex);
|
||||
|
||||
slotWindowSplit(mscore->splitScreen());
|
||||
connect(mscore, &MuseScore::windowSplit,
|
||||
this, &ScoreComparisonTool::slotWindowSplit);
|
||||
}
|
||||
|
||||
updateDiff();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// ScoreComparisonTool::updateDiffView
|
||||
//---------------------------------------------------------
|
||||
|
||||
void ScoreComparisonTool::updateDiffView(Mode mode)
|
||||
{
|
||||
switch(mode) {
|
||||
case Mode::RAW:
|
||||
if (!_rawModel && _diff) {
|
||||
_rawModel = new RawScoreDiffModel(_diff, true, this);
|
||||
connect(this, &ScoreComparisonTool::diffUpdated,
|
||||
_rawModel, &RawScoreDiffModel::update);
|
||||
_ui->rawDiffView->setModel(_rawModel);
|
||||
}
|
||||
break;
|
||||
case Mode::INTELLIGENT:
|
||||
if (!_intelligentModel && _diff) {
|
||||
_intelligentModel = new ScoreDiffModel(_diff, this);
|
||||
connect(this, &ScoreComparisonTool::diffAboutToBeUpdated,
|
||||
_intelligentModel, &ScoreDiffModel::diffAboutToBeUpdated);
|
||||
connect(this, &ScoreComparisonTool::diffUpdated,
|
||||
_intelligentModel, &ScoreDiffModel::diffUpdated);
|
||||
_ui->intelligentDiffView->setModel(_intelligentModel);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// ScoreComparisonTool::updateDiffTitle
|
||||
//---------------------------------------------------------
|
||||
|
||||
void ScoreComparisonTool::updateDiffTitle()
|
||||
{
|
||||
if (_diff)
|
||||
_ui->diffWidgetBox->setTitle(
|
||||
tr("Comparison of \"%1\" and \"%2\"")
|
||||
.arg(_diff->score1()->title())
|
||||
.arg(_diff->score2()->title())
|
||||
);
|
||||
else
|
||||
_ui->diffWidgetBox->setTitle(tr("Comparison"));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// ScoreComparisonTool::setMode
|
||||
//---------------------------------------------------------
|
||||
|
||||
void ScoreComparisonTool::setMode(Mode mode)
|
||||
{
|
||||
if (_mode == mode)
|
||||
return;
|
||||
_mode = mode;
|
||||
updateDiffView(mode);
|
||||
switch(mode) {
|
||||
case Mode::RAW:
|
||||
if (!_ui->rawModeRadioButton->isChecked())
|
||||
_ui->rawModeRadioButton->setChecked(true);
|
||||
_ui->diffWidget->setCurrentWidget(_ui->pageRawDiff);
|
||||
break;
|
||||
case Mode::INTELLIGENT:
|
||||
if (!_ui->intelligentModeRadioButton->isChecked())
|
||||
_ui->intelligentModeRadioButton->setChecked(true);
|
||||
_ui->diffWidget->setCurrentWidget(_ui->pageIntelligentDiff);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// ScoreComparisonTool::compare
|
||||
//---------------------------------------------------------
|
||||
|
||||
void ScoreComparisonTool::compare(Score* s1, Score* s2)
|
||||
{
|
||||
invalidateDiff();
|
||||
if (!s1 || !s2)
|
||||
return;
|
||||
_diff = new ScoreDiff(s1, s2);
|
||||
connect(s1, &QObject::destroyed, this, &ScoreComparisonTool::invalidateDiff);
|
||||
connect(s2, &QObject::destroyed, this, &ScoreComparisonTool::invalidateDiff);
|
||||
updateDiffView(_mode);
|
||||
updateDiffTitle();
|
||||
mscore->setCurrentScores(s1, s2);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// ScoreComparisonTool::invalidateDiff
|
||||
//---------------------------------------------------------
|
||||
|
||||
void ScoreComparisonTool::invalidateDiff()
|
||||
{
|
||||
if (_rawModel) {
|
||||
_rawModel->deleteLater();
|
||||
_rawModel = nullptr;
|
||||
}
|
||||
if (_intelligentModel) {
|
||||
_intelligentModel->deleteLater();
|
||||
_intelligentModel = nullptr;
|
||||
}
|
||||
|
||||
if (_diff) {
|
||||
disconnect(_diff->score1(), 0, this, 0);
|
||||
disconnect(_diff->score2(), 0, this, 0);
|
||||
delete _diff;
|
||||
_diff = nullptr;
|
||||
}
|
||||
|
||||
updateDiffTitle();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// ScoreComparisonTool::updateDiff
|
||||
//---------------------------------------------------------
|
||||
|
||||
void ScoreComparisonTool::updateDiff()
|
||||
{
|
||||
if (isVisible() && _diff && !_diff->updated()) {
|
||||
emit diffAboutToBeUpdated();
|
||||
_diff->update();
|
||||
emit diffUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// ScoreComparisonTool::openScoreVersion
|
||||
// Opens the proper score version if it is not opened
|
||||
// and returns the score object. Does not switch active
|
||||
// tab as the score comparison tool may need some
|
||||
// specific tabs configuration.
|
||||
//---------------------------------------------------------
|
||||
|
||||
Score* ScoreComparisonTool::openScoreVersion(const ScoreVersion& ver)
|
||||
{
|
||||
Score* s;
|
||||
if (ver.recent) {
|
||||
s = ver.score;
|
||||
if (!s)
|
||||
s = mscore->openScore(ver.fileInfo.absoluteFilePath(), /* switchTab */ false);
|
||||
}
|
||||
else {
|
||||
QString baseName;
|
||||
if (ver.score)
|
||||
baseName = ver.score->masterScore()->fileInfo()->completeBaseName();
|
||||
else
|
||||
baseName = ver.fileInfo.completeBaseName();
|
||||
|
||||
QTemporaryFile* tmp = mscore->getTemporaryScoreFileCopy(
|
||||
ver.fileInfo,
|
||||
QString("[%1] %2.XXXXXX").arg(ver.name).arg(baseName)
|
||||
);
|
||||
if (tmp) {
|
||||
s = mscore->openScore(tmp->fileName(), /* switchTab */ false);
|
||||
if (s)
|
||||
s->masterScore()->setReadOnly(true);
|
||||
delete tmp;
|
||||
// let the score know about the temporary file deletion
|
||||
s->masterScore()->fileInfo()->refresh();
|
||||
updateScoreVersions(s);
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// ScoreComparisonTool::on_compareButton_clicked
|
||||
//---------------------------------------------------------
|
||||
|
||||
void ScoreComparisonTool::on_compareButton_clicked()
|
||||
{
|
||||
const int idx1 = _ui->version1ComboBox->currentIndex();
|
||||
const int idx2 = _ui->version2ComboBox->currentIndex();
|
||||
if (idx1 < 0 || idx2 < 0) // no scores to compare
|
||||
return;
|
||||
const ScoreVersion& ver1 = _scoreVersionsModel1->getScoreVersion(idx1);
|
||||
const ScoreVersion& ver2 = _scoreVersionsModel2->getScoreVersion(idx2);
|
||||
Score* s1 = openScoreVersion(ver1);
|
||||
Score* s2 = openScoreVersion(ver2);
|
||||
compare(s1, s2);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// ScoreComparisonTool::selectedVersionsChanged
|
||||
// Disables Compare button if there are no versions
|
||||
// selected for comparison.
|
||||
//---------------------------------------------------------
|
||||
|
||||
void ScoreComparisonTool::selectedVersionsChanged()
|
||||
{
|
||||
const int idx1 = _ui->version1ComboBox->currentIndex();
|
||||
const int idx2 = _ui->version2ComboBox->currentIndex();
|
||||
_ui->compareButton->setEnabled(idx1 >= 0 && idx2 >= 0);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// ScoreComparisonTool::updateScoreVersions
|
||||
//---------------------------------------------------------
|
||||
|
||||
void ScoreComparisonTool::updateScoreVersions(const Score* s)
|
||||
{
|
||||
if (_scoreVersionsModel1 && _scoreVersionsModel1->score() == s) {
|
||||
_scoreVersionsModel1->update();
|
||||
resetVersion1ComboBox();
|
||||
}
|
||||
if (_scoreVersionsModel2 && _scoreVersionsModel2->score() == s) {
|
||||
_scoreVersionsModel2->update();
|
||||
resetVersion2ComboBox();
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// ScoreComparisonTool::on_browseFileButton_clicked
|
||||
//---------------------------------------------------------
|
||||
|
||||
void ScoreComparisonTool::on_browseFileButton_clicked()
|
||||
{
|
||||
Score* prevScore = mscore->currentScore();
|
||||
mscore->loadFiles(/* switchTab */ true, /* singleFile */ true);
|
||||
Score* loadedScore = mscore->currentScore();
|
||||
if (loadedScore == prevScore) // we didn't load anything?
|
||||
return;
|
||||
// ensure that we display this score in split-screen mode
|
||||
mscore->setCurrentScores(loadedScore, loadedScore);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// ScoreComparisonTool::resetVersion1ComboBox
|
||||
//---------------------------------------------------------
|
||||
|
||||
void ScoreComparisonTool::resetVersion1ComboBox()
|
||||
{
|
||||
if (_scoreVersionsModel1) {
|
||||
_ui->version1ComboBox->setCurrentIndex(
|
||||
_scoreVersionsModel1->getPosition(ScoreVersion::INDEX_CURRENT));
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// ScoreComparisonTool::on_score1ComboBox_currentIndexChanged
|
||||
//---------------------------------------------------------
|
||||
|
||||
void ScoreComparisonTool::on_score1ComboBox_currentIndexChanged(int idx)
|
||||
{
|
||||
if (_scoreVersionsModel1) {
|
||||
Score* s = _scoreListModel->getScore(idx);
|
||||
_scoreVersionsModel1->setScore(s ? s->masterScore() : nullptr);
|
||||
resetVersion1ComboBox();
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// ScoreComparisonTool::resetVersion2ComboBox
|
||||
//---------------------------------------------------------
|
||||
|
||||
void ScoreComparisonTool::resetVersion2ComboBox()
|
||||
{
|
||||
if (_scoreVersionsModel2) {
|
||||
int index = -1;
|
||||
if (!mscore->splitScreen())
|
||||
index = _scoreVersionsModel2->getPosition(ScoreVersion::INDEX_SESSION_START);
|
||||
if (index < 0)
|
||||
index = _scoreVersionsModel2->getPosition(ScoreVersion::INDEX_CURRENT);
|
||||
_ui->version2ComboBox->setCurrentIndex(index);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// ScoreComparisonTool::on_score2ComboBox_currentIndexChanged
|
||||
//---------------------------------------------------------
|
||||
|
||||
void ScoreComparisonTool::on_score2ComboBox_currentIndexChanged(int idx)
|
||||
{
|
||||
if (_scoreVersionsModel2) {
|
||||
Score* s = _scoreListModel->getScore(idx);
|
||||
_scoreVersionsModel2->setScore(s ? s->masterScore() : nullptr);
|
||||
resetVersion2ComboBox();
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// ScoreComparisonTool::on_rawModeRadioButton_toggled
|
||||
//---------------------------------------------------------
|
||||
|
||||
void ScoreComparisonTool::on_rawModeRadioButton_toggled(bool checked)
|
||||
{
|
||||
if (checked)
|
||||
setMode(Mode::RAW);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// ScoreComparisonTool::on_intelligentModeRadioButton_toggled
|
||||
//---------------------------------------------------------
|
||||
|
||||
void ScoreComparisonTool::on_intelligentModeRadioButton_toggled(bool checked)
|
||||
{
|
||||
if (checked)
|
||||
setMode(Mode::INTELLIGENT);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// ScoreComparisonTool::on_intelligentDiffView_activated
|
||||
//---------------------------------------------------------
|
||||
|
||||
void ScoreComparisonTool::on_intelligentDiffView_activated(const QModelIndex& index)
|
||||
{
|
||||
const BaseDiff* diff = _intelligentModel->diffItem(index);
|
||||
|
||||
const ScoreElement* el[2];
|
||||
bool select[2] { true, true };
|
||||
switch(diff->itemType()) {
|
||||
case ItemType::ELEMENT:
|
||||
{
|
||||
const ElementDiff* elDiff = static_cast<const ElementDiff*>(diff);
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
if (elDiff->el[i])
|
||||
el[i] = elDiff->el[i];
|
||||
else {
|
||||
if (elDiff->ctx[i]->isElement() || !elDiff->before[i])
|
||||
el[i] = elDiff->ctx[i];
|
||||
else
|
||||
el[i] = elDiff->before[i];
|
||||
select[i] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
std::copy(diff->ctx, diff->ctx + 2, el);
|
||||
break;
|
||||
}
|
||||
|
||||
showElement(el[0], select[0]);
|
||||
showElement(el[1], select[1]);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// ScoreComparisonTool::showElement
|
||||
//---------------------------------------------------------
|
||||
|
||||
void ScoreComparisonTool::showElement(const ScoreElement* se, bool select)
|
||||
{
|
||||
if (!se)
|
||||
return;
|
||||
|
||||
ScoreView* sv1 = mscore->getTab1()->view();
|
||||
Score* score1 = (sv1 && sv1->isVisible()) ? sv1->score() : nullptr;
|
||||
ScoreView* sv2 = mscore->getTab2() ? mscore->getTab2()->view() : nullptr;
|
||||
Score* score2 = (sv2 && sv2->isVisible()) ? sv2->score() : nullptr;
|
||||
const Element* e = se->isElement() ? toElement(se) : nullptr;
|
||||
Score* score = se->score();
|
||||
|
||||
score->deselectAll();
|
||||
if (select && e && (score1 == score || score2 == score)) {
|
||||
Element* el = const_cast<Element*>(e);
|
||||
if (el->isChordRest())
|
||||
score->select(el, SelectType::RANGE);
|
||||
else
|
||||
score->select(el);
|
||||
}
|
||||
|
||||
if (score1 == score) {
|
||||
bool move = sv1->moveWhenInactive(true);
|
||||
if (e) {
|
||||
sv1->adjustCanvasPosition(e, false);
|
||||
sv1->update();
|
||||
}
|
||||
sv1->moveWhenInactive(move);
|
||||
}
|
||||
if (score2 == score) {
|
||||
bool move = sv2->moveWhenInactive(true);
|
||||
if (e) {
|
||||
sv2->adjustCanvasPosition(e, false);
|
||||
sv2->update();
|
||||
}
|
||||
sv2->moveWhenInactive(move);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// ScoreComparisonTool::slotWindowSplit
|
||||
//---------------------------------------------------------
|
||||
|
||||
void ScoreComparisonTool::slotWindowSplit(bool split)
|
||||
{
|
||||
ScoreTab* tab1 = mscore->getTab1();
|
||||
|
||||
if (ScoreTab* tab2 = mscore->getTab2()) {
|
||||
if (split) {
|
||||
disconnect(tab1->getTab(), &QTabBar::currentChanged,
|
||||
_ui->score2ComboBox, &QComboBox::setCurrentIndex);
|
||||
_ui->score2ComboBox->setCurrentIndex(tab2->currentIndex());
|
||||
connect(tab2->getTab(), &QTabBar::currentChanged,
|
||||
_ui->score2ComboBox, &QComboBox::setCurrentIndex,
|
||||
Qt::UniqueConnection
|
||||
);
|
||||
}
|
||||
else
|
||||
disconnect(tab2->getTab(), &QTabBar::currentChanged,
|
||||
_ui->score2ComboBox, &QComboBox::setCurrentIndex);
|
||||
}
|
||||
|
||||
if (!split) {
|
||||
_ui->score2ComboBox->setCurrentIndex(tab1->currentIndex());
|
||||
connect(tab1->getTab(), &QTabBar::currentChanged,
|
||||
_ui->score2ComboBox, &QComboBox::setCurrentIndex,
|
||||
Qt::UniqueConnection
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
95
mscore/scorecmp/scorecmp.h
Normal file
95
mscore/scorecmp/scorecmp.h
Normal file
|
@ -0,0 +1,95 @@
|
|||
//=============================================================================
|
||||
// MuseScore
|
||||
// Music Composition & Notation
|
||||
//
|
||||
// Copyright (C) 2018 Werner Schweer
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2
|
||||
// as published by the Free Software Foundation and appearing in
|
||||
// the file LICENCE.GPL
|
||||
//=============================================================================
|
||||
|
||||
#ifndef __SCORECMP_H__
|
||||
#define __SCORECMP_H__
|
||||
|
||||
namespace Ui {
|
||||
class ScoreComparisonTool;
|
||||
}
|
||||
|
||||
namespace Ms {
|
||||
|
||||
class Score;
|
||||
class ScoreElement;
|
||||
class ScoreDiff;
|
||||
class RawScoreDiffModel;
|
||||
class ScoreDiffModel;
|
||||
class ScoreListModel;
|
||||
struct ScoreVersion;
|
||||
class ScoreVersionListModel;
|
||||
|
||||
//---------------------------------------------------------
|
||||
// ScoreComparisonTool
|
||||
//---------------------------------------------------------
|
||||
|
||||
class ScoreComparisonTool : public QDockWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum class Mode { RAW, INTELLIGENT };
|
||||
|
||||
private:
|
||||
Ui::ScoreComparisonTool* _ui;
|
||||
Mode _mode;
|
||||
|
||||
ScoreListModel* _scoreListModel = nullptr;
|
||||
ScoreVersionListModel* _scoreVersionsModel1 = nullptr;
|
||||
ScoreVersionListModel* _scoreVersionsModel2 = nullptr;
|
||||
|
||||
ScoreDiff* _diff = nullptr;
|
||||
RawScoreDiffModel* _rawModel = nullptr;
|
||||
ScoreDiffModel* _intelligentModel = nullptr;
|
||||
|
||||
void updateDiffView(Mode mode);
|
||||
void updateDiffTitle();
|
||||
void resetVersion1ComboBox();
|
||||
void resetVersion2ComboBox();
|
||||
Score* openScoreVersion(const ScoreVersion& ver);
|
||||
void showElement(const ScoreElement* se, bool select);
|
||||
|
||||
private slots:
|
||||
void on_compareButton_clicked();
|
||||
void on_browseFileButton_clicked();
|
||||
void on_score1ComboBox_currentIndexChanged(int);
|
||||
void on_score2ComboBox_currentIndexChanged(int);
|
||||
void on_rawModeRadioButton_toggled(bool);
|
||||
void on_intelligentModeRadioButton_toggled(bool);
|
||||
void on_intelligentDiffView_activated(const QModelIndex&);
|
||||
void selectedVersionsChanged();
|
||||
|
||||
protected:
|
||||
void changeEvent(QEvent* e) override;
|
||||
void showEvent(QShowEvent* e) override;
|
||||
|
||||
signals:
|
||||
void diffAboutToBeUpdated();
|
||||
void diffUpdated();
|
||||
|
||||
public:
|
||||
explicit ScoreComparisonTool(QWidget* parent = nullptr);
|
||||
~ScoreComparisonTool();
|
||||
|
||||
void setMode(Mode mode);
|
||||
Mode mode() const { return _mode; }
|
||||
|
||||
void compare(Score* s1, Score* s2);
|
||||
|
||||
public slots:
|
||||
void slotWindowSplit(bool);
|
||||
void invalidateDiff();
|
||||
void updateDiff();
|
||||
void updateScoreVersions(const Score*);
|
||||
};
|
||||
|
||||
} // namespace Ms
|
||||
#endif
|
226
mscore/scorecmp/scorecmp_tool.ui
Normal file
226
mscore/scorecmp/scorecmp_tool.ui
Normal file
|
@ -0,0 +1,226 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ScoreComparisonTool</class>
|
||||
<widget class="QDockWidget" name="ScoreComparisonTool">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>858</width>
|
||||
<height>247</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="accessibleName">
|
||||
<string>Score Comparison Tool</string>
|
||||
</property>
|
||||
<property name="accessibleDescription">
|
||||
<string>A tool to examine differences between the chosen scores</string>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Score Comparison Tool</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="dockWidgetContents">
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>Choose scores to compare:</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="score1Label">
|
||||
<property name="text">
|
||||
<string>Score 1:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>score1ComboBox</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="score1ComboBox">
|
||||
<property name="accessibleName">
|
||||
<string>Score 1</string>
|
||||
</property>
|
||||
<property name="accessibleDescription">
|
||||
<string>Choose the first score to compare</string>
|
||||
</property>
|
||||
<property name="minimumContentsLength">
|
||||
<number>20</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="score2Label">
|
||||
<property name="text">
|
||||
<string>Score 2:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>score2ComboBox</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="score2ComboBox">
|
||||
<property name="accessibleName">
|
||||
<string>Score 2</string>
|
||||
</property>
|
||||
<property name="accessibleDescription">
|
||||
<string>Choose the second score to compare</string>
|
||||
</property>
|
||||
<property name="minimumContentsLength">
|
||||
<number>20</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QComboBox" name="version1ComboBox">
|
||||
<property name="accessibleName">
|
||||
<string>Score version 1</string>
|
||||
</property>
|
||||
<property name="accessibleDescription">
|
||||
<string>Choose a version of the first score to compare</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QComboBox" name="version2ComboBox">
|
||||
<property name="accessibleName">
|
||||
<string>Score version 2</string>
|
||||
</property>
|
||||
<property name="accessibleDescription">
|
||||
<string>Choose a version of the second score to compare</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QPushButton" name="browseFileButton">
|
||||
<property name="toolTip">
|
||||
<string>Browse files for comparison</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Browse</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1" colspan="2">
|
||||
<widget class="QPushButton" name="compareButton">
|
||||
<property name="toolTip">
|
||||
<string>Perform comparison of chosen scores</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Compare</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Diff mode</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="rawModeRadioButton">
|
||||
<property name="text">
|
||||
<string>Raw</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="intelligentModeRadioButton">
|
||||
<property name="text">
|
||||
<string>Intelligent</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QGroupBox" name="diffWidgetBox">
|
||||
<property name="title">
|
||||
<string>Comparison</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<item>
|
||||
<widget class="QStackedWidget" name="diffWidget">
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="pageRawDiff">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QListView" name="rawDiffView">
|
||||
<property name="textElideMode">
|
||||
<enum>Qt::ElideNone</enum>
|
||||
</property>
|
||||
<property name="verticalScrollMode">
|
||||
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="pageIntelligentDiff">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QListView" name="intelligentDiffView"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>score1ComboBox</tabstop>
|
||||
<tabstop>version1ComboBox</tabstop>
|
||||
<tabstop>score2ComboBox</tabstop>
|
||||
<tabstop>version2ComboBox</tabstop>
|
||||
<tabstop>browseFileButton</tabstop>
|
||||
<tabstop>compareButton</tabstop>
|
||||
<tabstop>rawModeRadioButton</tabstop>
|
||||
<tabstop>intelligentModeRadioButton</tabstop>
|
||||
<tabstop>intelligentDiffView</tabstop>
|
||||
<tabstop>rawDiffView</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
132
mscore/scorecmp/scorediffmodel.cpp
Normal file
132
mscore/scorecmp/scorediffmodel.cpp
Normal file
|
@ -0,0 +1,132 @@
|
|||
//=============================================================================
|
||||
// MuseScore
|
||||
// Music Composition & Notation
|
||||
//
|
||||
// Copyright (C) 2018 Werner Schweer
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2
|
||||
// as published by the Free Software Foundation and appearing in
|
||||
// the file LICENCE.GPL
|
||||
//=============================================================================
|
||||
|
||||
#include "scorediffmodel.h"
|
||||
|
||||
#include "libmscore/scorediff.h"
|
||||
|
||||
namespace Ms {
|
||||
|
||||
//---------------------------------------------------------
|
||||
// RawScoreDiffModel::RawScoreDiffModel
|
||||
//---------------------------------------------------------
|
||||
|
||||
RawScoreDiffModel::RawScoreDiffModel(ScoreDiff* d, bool skipEqual, QObject* parent)
|
||||
: QAbstractListModel(parent), _diff(d), _skipEqual(skipEqual)
|
||||
{
|
||||
update();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// RawScoreDiffModel::update
|
||||
//---------------------------------------------------------
|
||||
|
||||
void RawScoreDiffModel::update() {
|
||||
beginResetModel();
|
||||
_textDiffs.clear();
|
||||
for (const TextDiff& diff : _diff->textDiffs()) {
|
||||
if (_skipEqual && diff.type == DiffType::EQUAL)
|
||||
continue;
|
||||
if (diff.type == DiffType::REPLACE) {
|
||||
// Push this item twice. First will be shown as DELETE,
|
||||
// second as INSERT.
|
||||
_textDiffs.push_back(&diff);
|
||||
}
|
||||
_textDiffs.push_back(&diff);
|
||||
}
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// RawScoreDiffModel::rowCount
|
||||
//---------------------------------------------------------
|
||||
|
||||
int RawScoreDiffModel::rowCount(const QModelIndex& parent) const
|
||||
{
|
||||
if (parent.isValid())
|
||||
return 0;
|
||||
return _textDiffs.size();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// RawScoreDiffModel::data
|
||||
//---------------------------------------------------------
|
||||
|
||||
QVariant RawScoreDiffModel::data(const QModelIndex& index, int role) const
|
||||
{
|
||||
const int row = index.row();
|
||||
if (row < 0 || row >= int(_textDiffs.size()))
|
||||
return QVariant();
|
||||
|
||||
const TextDiff& diff = *_textDiffs[row];
|
||||
switch(role) {
|
||||
case Qt::DisplayRole:
|
||||
{
|
||||
DiffType type = diff.type;
|
||||
if (diff.type == DiffType::REPLACE)
|
||||
type = (row == 0 || _textDiffs[row - 1] != &diff) ? DiffType::DELETE : DiffType::INSERT;
|
||||
return diff.toString(type);
|
||||
}
|
||||
case Qt::BackgroundRole:
|
||||
switch(diff.type) {
|
||||
case DiffType::DELETE:
|
||||
return QBrush(Qt::red);
|
||||
case DiffType::INSERT:
|
||||
return QBrush(Qt::green);
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// ScoreDiffModel::rowCount
|
||||
//---------------------------------------------------------
|
||||
|
||||
int ScoreDiffModel::rowCount(const QModelIndex& parent) const
|
||||
{
|
||||
if (parent.isValid())
|
||||
return 0;
|
||||
return _diff->diffs().size();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// ScoreDiffModel::data
|
||||
//---------------------------------------------------------
|
||||
|
||||
QVariant ScoreDiffModel::data(const QModelIndex& index, int role) const
|
||||
{
|
||||
const int row = index.row();
|
||||
if (row < 0 || row >= int(_diff->diffs().size()))
|
||||
return QVariant();
|
||||
|
||||
const BaseDiff& diff = *_diff->diffs()[row];
|
||||
switch(role) {
|
||||
case Qt::DisplayRole:
|
||||
return diff.toString();
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// ScoreDiffModel::diffItem
|
||||
//---------------------------------------------------------
|
||||
|
||||
const BaseDiff* ScoreDiffModel::diffItem(const QModelIndex& index) const
|
||||
{
|
||||
const int row = index.row();
|
||||
if (row < 0 || row >= int(_diff->diffs().size()))
|
||||
return nullptr;
|
||||
return _diff->diffs()[row];
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue