Skip to content

Commit

Permalink
fix #35466
Browse files Browse the repository at this point in the history
  • Loading branch information
wschweer committed Nov 6, 2014
1 parent 0ff91aa commit 5ed2bc8
Show file tree
Hide file tree
Showing 10 changed files with 91 additions and 54 deletions.
13 changes: 10 additions & 3 deletions libmscore/edit.cpp
Expand Up @@ -2434,19 +2434,26 @@ void Score::checkSpanner(int startTick, int endTick)

if (s->type() == Element::Type::SLUR) {
Segment* seg = tick2segmentMM(s->tick(), false, Segment::Type::ChordRest);
if (!seg || !seg->element(s->track()))
if (!seg || !seg->element(s->track())) {
qDebug("checkSpanner::remove (1)");
sl.append(s);
}
else {
seg = tick2segmentMM(s->tick2(), false, Segment::Type::ChordRest);
if (!seg || !seg->element(s->track2()))
if (!seg || !seg->element(s->track2())) {
qDebug("checkSpanner::remove (2) %d - tick %d track %d",
s->tick(), s->tick2(), s->track2());
sl.append(s);
}
}
}
else {
// remove spanner if there is no start element
s->computeStartElement();
if (!s->startElement())
if (!s->startElement()) {
sl.append(s);
qDebug("checkSpanner::remove (3)");
}
else {
if (s->tick2() > lastTick)
s->undoChangeProperty(P_ID::SPANNER_TICKS, lastTick - s->tick());
Expand Down
4 changes: 2 additions & 2 deletions libmscore/element.cpp
Expand Up @@ -584,7 +584,7 @@ QPointF Element::canvasPos() const
if (_flags & ElementFlag::ON_STAFF) {
System* system = nullptr;
if (parent()->type() == Element::Type::SEGMENT)
system = static_cast<Segment*>(parent())->measure()->system();
system = static_cast<Segment*>(parent())->system();
else if (parent()->type() == Element::Type::MEASURE) // used in measure number
system = static_cast<Measure*>(parent())->system();
else if (parent()->type() == Element::Type::SYSTEM)
Expand Down Expand Up @@ -727,7 +727,7 @@ bool Element::readProperties(XmlReader& e)
const QStringRef& tag(e.name());

if (tag == "track")
setTrack(e.readInt());
setTrack(e.readInt() + e.trackOffset());
else if (tag == "color")
setColor(e.readColor());
else if (tag == "visible")
Expand Down
6 changes: 4 additions & 2 deletions libmscore/mscore.h
Expand Up @@ -15,8 +15,8 @@

namespace Ms {

#define MSC_VERSION "2.00"
static const int MSCVERSION = 200;
#define MSC_VERSION "2.01"
static const int MSCVERSION = 201;

// History:
// 1.3 added staff->_barLineSpan
Expand Down Expand Up @@ -46,6 +46,8 @@ static const int MSCVERSION = 200;
// - symbol numbers in TextLine() replaced by symbol names
// TextStyle: frameWidth, paddingWidth are now in Spatium units (instead of mm)
// 2.00 (Version 2.0)
// 2.01 save SlurSegment position relative to staff



class MStyle;
Expand Down
57 changes: 30 additions & 27 deletions libmscore/paste.cpp
Expand Up @@ -69,11 +69,10 @@ static void transposeChord(Chord* c, Interval srcTranspose)
// return false if paste fails
//---------------------------------------------------------

bool Score::pasteStaff(XmlReader& e, Segment* dst, int staffIdx)
bool Score::pasteStaff(XmlReader& e, Segment* dst, int dstStaff)
{
Q_ASSERT(dst->segmentType() == Segment::Type::ChordRest);
QList<Chord*> graceNotes;
int dstStaffStart = staffIdx;
int dstTick = dst->tick();
bool done = false;
bool pasted = false;
Expand All @@ -86,11 +85,15 @@ bool Score::pasteStaff(XmlReader& e, Segment* dst, int staffIdx)
break;
}
QString version = e.attribute("version", "NONE");
if (version != MSC_VERSION)
break;
if (!MScore::testMode) {
if (version != MSC_VERSION) {
qDebug("pasteStaff: bad version");
break;
}
}
int tickStart = e.intAttribute("tick", 0);
tickLen = e.intAttribute("len", 0);
int srcStaffStart = e.intAttribute("staff", 0);
int staffStart = e.intAttribute("staff", 0);
staves = e.intAttribute("staves", 0);
int voiceOffset[VOICES];
std::fill(voiceOffset,voiceOffset+VOICES,-1);
Expand All @@ -109,10 +112,12 @@ bool Score::pasteStaff(XmlReader& e, Segment* dst, int staffIdx)
e.setTransposeDiatonic(0);

int srcStaffIdx = e.attribute("id", "0").toInt();
int dstStaffIdx = srcStaffIdx - srcStaffStart + dstStaffStart;

if (dstStaffIdx >= nstaves()) {
done = true; // break main loop, nothing more to paste
e.setTrack(srcStaffIdx * VOICES);
e.setTrackOffset((dstStaff - staffStart) * VOICES);
int dstStaffIdx = e.track() / VOICES;
if (dstStaffIdx >= dst->score()->nstaves()) {
qDebug("paste beyond staves");
done = true;
break;
}

Expand Down Expand Up @@ -164,9 +169,6 @@ bool Score::pasteStaff(XmlReader& e, Segment* dst, int staffIdx)
cr->setTrack(e.track());
cr->read(e);
cr->setSelected(false);
int voice = cr->voice();
int track = dstStaffIdx * VOICES + voice;
cr->setTrack(track);
int tick = e.tick();
if (cr->isGrace())
graceNotes.push_back(static_cast<Chord*>(cr));
Expand Down Expand Up @@ -200,15 +202,15 @@ bool Score::pasteStaff(XmlReader& e, Segment* dst, int staffIdx)
Spanner* sp = static_cast<Spanner*>(Element::name2Element(tag, this));
sp->setAnchor(Spanner::Anchor::SEGMENT);
sp->read(e);
sp->setTrack(dstStaffIdx * VOICES);
sp->setTrack2(dstStaffIdx * VOICES);
sp->setTrack(e.track());
sp->setTrack2(e.track());
sp->setTick(e.tick());
addSpanner(sp);
}
else if (tag == "Slur") {
Spanner* sp = static_cast<Spanner*>(Element::name2Element(tag, this));
sp->read(e);
sp->setTrack(dstStaffIdx * VOICES);
sp->setTrack(e.track());
sp->setTick(e.tick());
undoAddElement(sp);
}
Expand All @@ -231,7 +233,7 @@ bool Score::pasteStaff(XmlReader& e, Segment* dst, int staffIdx)
Lyrics* lyrics = new Lyrics(this);
lyrics->setTrack(e.track());
lyrics->read(e);
lyrics->setTrack(dstStaffIdx * VOICES);
lyrics->setTrack(e.track());
int tick = e.tick();
Segment* segment = tick2segment(tick);
if (segment) {
Expand All @@ -248,9 +250,9 @@ bool Score::pasteStaff(XmlReader& e, Segment* dst, int staffIdx)
Harmony* harmony = new Harmony(this);
harmony->setTrack(e.track());
harmony->read(e);
harmony->setTrack(dstStaffIdx * VOICES);
harmony->setTrack(e.track());
// transpose
Part* partDest = staff(dstStaffIdx)->part();
Part* partDest = staff(e.track() / VOICES)->part();
Interval interval = partDest->instr()->transpose();
if (!styleB(StyleIdx::concertPitch) && !interval.isZero()) {
interval.flip();
Expand All @@ -262,11 +264,11 @@ bool Score::pasteStaff(XmlReader& e, Segment* dst, int staffIdx)
int tick = e.tick();
Measure* m = tick2measure(tick);
Segment* seg = m->undoGetSegment(Segment::Type::ChordRest, tick);
if (seg->findAnnotationOrElement(Element::Type::HARMONY, dstStaffIdx * VOICES, dstStaffIdx * VOICES)) {
if (seg->findAnnotationOrElement(Element::Type::HARMONY, e.track(), e.track())) {
QList<Element*> elements;
foreach (Element* el, seg->annotations()) {
if (el->type() == Element::Type::HARMONY
&& el->track() == dstStaffIdx * VOICES) {
&& el->track() == e.track()) {
elements.append(el);
}
}
Expand All @@ -290,7 +292,7 @@ bool Score::pasteStaff(XmlReader& e, Segment* dst, int staffIdx)
|| tag == "FiguredBass"
) {
Element* el = Element::name2Element(tag, this);
el->setTrack(dstStaffIdx * VOICES); // a valid track might be necessary for el->read() to work
el->setTrack(e.track()); // a valid track might be necessary for el->read() to work

int tick = e.tick();
Measure* m = tick2measure(tick);
Expand All @@ -300,13 +302,13 @@ bool Score::pasteStaff(XmlReader& e, Segment* dst, int staffIdx)

// be sure to paste the element in the destination track;
// setting track needs to be repeated, as it might have been overwritten by el->read()
el->setTrack(dstStaffIdx * VOICES);
el->setTrack(e.track());
undoAddElement(el);
}
else if (tag == "Clef") {
Clef* clef = new Clef(this);
clef->read(e);
clef->setTrack(dstStaffIdx * VOICES);
clef->setTrack(e.track());
int tick = e.tick();
Measure* m = tick2measure(tick);
if (m->tick() && m->tick() == tick)
Expand All @@ -318,7 +320,7 @@ bool Score::pasteStaff(XmlReader& e, Segment* dst, int staffIdx)
else if (tag == "Breath") {
Breath* breath = new Breath(this);
breath->read(e);
breath->setTrack(dstStaffIdx * VOICES);
breath->setTrack(e.track());
int tick = e.tick();
Measure* m = tick2measure(tick);
Segment* segment = m->undoGetSegment(Segment::Type::Breath, tick);
Expand Down Expand Up @@ -365,10 +367,10 @@ bool Score::pasteStaff(XmlReader& e, Segment* dst, int staffIdx)
if (pasted) { //select only if we pasted something
Segment* s1 = tick2segment(dstTick);
Segment* s2 = tick2segment(dstTick + tickLen);
int endStaff = dstStaffStart + staves;
int endStaff = dstStaff + staves;
if (endStaff > nstaves())
endStaff = nstaves();
_selection.setRange(s1, s2, dstStaffStart, endStaff);
_selection.setRange(s1, s2, dstStaff, endStaff);
_selection.updateSelectedElements();

//finding the first element that has a track
Expand All @@ -379,7 +381,7 @@ bool Score::pasteStaff(XmlReader& e, Segment* dst, int staffIdx)
if (s2)
s2 = s2->next1MM();
while (!found && s != s2) {
for (int i = dstStaffStart * VOICES; i < (endStaff + 1) * VOICES; i++) {
for (int i = dstStaff * VOICES; i < (endStaff + 1) * VOICES; i++) {
e = s->element(i);
if (e) {
found = true;
Expand Down Expand Up @@ -793,6 +795,7 @@ PasteStatus Score::cmdPaste(const QMimeData* ms, MuseScoreView* view)
XmlReader e(data);
e.setPasteMode(true);
if (!pasteStaff(e, cr->segment(),cr->staffIdx())) {
qDebug("paste failed");
return PasteStatus::TUPLET_CROSSES_BAR;
}
}
Expand Down
5 changes: 4 additions & 1 deletion libmscore/scorefile.cpp
Expand Up @@ -620,11 +620,14 @@ void Score::saveFile(QIODevice* f, bool msczFormat, bool onlySelection)
Xml xml(f);
xml.writeOmr = msczFormat;
xml.header();
xml.stag("museScore version=\"" MSC_VERSION "\"");
if (!MScore::testMode) {
xml.stag("museScore version=\"" MSC_VERSION "\"");
xml.tag("programVersion", VERSION);
xml.tag("programRevision", revision);
}
else {
xml.stag("museScore version=\"2.00\"");
}
write(xml, onlySelection);
xml.etag();
if (!parentScore())
Expand Down
7 changes: 6 additions & 1 deletion libmscore/select.cpp
Expand Up @@ -637,7 +637,12 @@ QByteArray Selection::staffMimeData() const

int ticks = tickEnd() - tickStart();
int staves = staffEnd() - staffStart();
xml.stag(QString("StaffList version=\"" MSC_VERSION "\" tick=\"%1\" len=\"%2\" staff=\"%3\" staves=\"%4\"").arg(tickStart()).arg(ticks).arg(staffStart()).arg(staves));
if (!MScore::testMode) {
xml.stag(QString("StaffList version=\"" MSC_VERSION "\" tick=\"%1\" len=\"%2\" staff=\"%3\" staves=\"%4\"").arg(tickStart()).arg(ticks).arg(staffStart()).arg(staves));
}
else {
xml.stag(QString("StaffList version=\"2.00\" tick=\"%1\" len=\"%2\" staff=\"%3\" staves=\"%4\"").arg(tickStart()).arg(ticks).arg(staffStart()).arg(staves));
}
Segment* seg1 = _startSegment;
Segment* seg2 = _endSegment;

Expand Down
19 changes: 16 additions & 3 deletions libmscore/slur.cpp
Expand Up @@ -49,8 +49,10 @@ SlurSegment::SlurSegment(Score* score)
SlurSegment::SlurSegment(const SlurSegment& b)
: SpannerSegment(b)
{
for (int i = 0; i < int(GripSlurSegment::GRIPS); ++i)
for (int i = 0; i < int(GripSlurSegment::GRIPS); ++i) {
ups[i] = b.ups[i];
ups[i].p = QPointF();
}
path = b.path;
autoAdjustOffset = QPointF();
}
Expand Down Expand Up @@ -451,6 +453,10 @@ void SlurSegment::read(XmlReader& e)
else if (!Element::readProperties(e))
e.unknown();
}
if ((staffIdx() > 0) && score()->mscVersion() < 201) {
//discard any user tweaking for older scores
setReadPos(QPointF());
}
}

//---------------------------------------------------------
Expand Down Expand Up @@ -545,6 +551,7 @@ void Slur::computeBezier(SlurSegment* ss, QPointF p6o)
p6 = t.map(p6) + pp3 - p6o;
//-----------------------------------


ss->path = QPainterPath();
ss->path.moveTo(QPointF());
ss->path.cubicTo(p3 + p3o - th, p4 + p4o - th, p2);
Expand All @@ -557,6 +564,10 @@ void Slur::computeBezier(SlurSegment* ss, QPointF p6o)
ss->shapePath.cubicTo(p3 + p3o - th, p4 + p4o - th, p2);
ss->shapePath.cubicTo(p4 +p4o + th, p3 + p3o + th, QPointF());

QPointF staffOffset;
if (ss->system() && ss->track() >= 0)
staffOffset = QPointF(0.0, -ss->system()->staff(ss->staffIdx())->y());

// translate back
t.reset();
t.translate(pp1.x(), pp1.y());
Expand All @@ -568,6 +579,9 @@ void Slur::computeBezier(SlurSegment* ss, QPointF p6o)
ss->ups[int(GripSlurSegment::END)].p = t.map(p2) - ss->ups[int(GripSlurSegment::END)].off * _spatium;
ss->ups[int(GripSlurSegment::DRAG)].p = t.map(p5);
ss->ups[int(GripSlurSegment::SHOULDER)].p = t.map(p6);

ss->path.translate(staffOffset);
ss->shapePath.translate(staffOffset);
}

//---------------------------------------------------------
Expand Down Expand Up @@ -629,8 +643,6 @@ void SlurSegment::layout(const QPointF& p1, const QPointF& p2)
}
}
}
if (system() && staffIdx() != -1)
setPos(QPointF(0.0, -system()->staff(staffIdx())->y()));
setbbox(path.boundingRect());
adjustReadPos();
}
Expand Down Expand Up @@ -1419,6 +1431,7 @@ void Slur::layout()
}
SlurSegment* segment = segmentAt(i);
segment->setSystem(system);
segment->setFlag(ElementFlag::ON_STAFF, true);

// case 1: one segment
if (sPos.system1 == sPos.system2) {
Expand Down
21 changes: 12 additions & 9 deletions libmscore/xml.h
Expand Up @@ -49,6 +49,7 @@ class XmlReader : public XmlStreamReader {
int _tick { 0 };
int _tickOffset { 0 };
int _track { 0 };
int _trackOffset { 0 };
bool _pasteMode { false }; // modifies read behaviour on paste operation
Measure* _lastMeasure { nullptr };
QList<Beam*> _beams;
Expand Down Expand Up @@ -92,17 +93,19 @@ class XmlReader : public XmlStreamReader {
void setDocName(const QString& s) { docName = s; }
QString getDocName() const { return docName; }

int tick() const { return _tick + _tickOffset; }
void initTick(int val) { _tick = val; }
void incTick(int val) { _tick += val; }
void setTickOffset(int val) { _tickOffset = val; }
int track() const { return _track; }
void setTrack(int val) { _track = val; }
bool pasteMode() const { return _pasteMode; }
void setPasteMode(bool v) { _pasteMode = v; }
int tick() const { return _tick + _tickOffset; }
void initTick(int val) { _tick = val; }
void incTick(int val) { _tick += val; }
void setTickOffset(int val) { _tickOffset = val; }
int track() const { return _track + _trackOffset; }
void setTrackOffset(int val) { _trackOffset = val; }
int trackOffset() const { return _trackOffset; }
void setTrack(int val) { _track = val; }
bool pasteMode() const { return _pasteMode; }
void setPasteMode(bool v) { _pasteMode = v; }

void addTuplet(Tuplet* s);
void addBeam(Beam* s) { _beams.append(s); }
void addBeam(Beam* s) { _beams.append(s); }

void setLastMeasure(Measure* m) { _lastMeasure = m; }
Measure* lastMeasure() const { return _lastMeasure; }
Expand Down
1 change: 0 additions & 1 deletion mtest/libmscore/copypaste/copypaste50-ref.mscx
Expand Up @@ -244,7 +244,6 @@
</Chord>
<Slur id="3">
<track>4</track>
<track2>0</track2>
</Slur>
<Chord>
<durationType>quarter</durationType>
Expand Down

1 comment on commit 5ed2bc8

@Jojo-Schmitz
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems to break ties pretty badly, see http://musescore.org/en/node/35466#comment-167061 ff

Please sign in to comment.