From 548fa0b7368d6dc83d1e648603925a35752ee51c Mon Sep 17 00:00:00 2001 From: ws Date: Thu, 31 Jul 2014 16:30:04 +0200 Subject: [PATCH] fix #25806 --- libmscore/articulation.cpp | 7 ++ libmscore/cmd.cpp | 10 +-- libmscore/property.cpp | 7 +- libmscore/property.h | 5 ++ libmscore/score.h | 1 - libmscore/slur.cpp | 134 +++++++++++++++++++++++++++++++++---- libmscore/slur.h | 13 ++++ libmscore/spanner.cpp | 47 +------------ libmscore/spanner.h | 4 +- libmscore/undo.cpp | 43 ------------ libmscore/undo.h | 20 ------ mscore/dragelement.cpp | 4 +- mscore/scoreview.cpp | 8 +-- 13 files changed, 167 insertions(+), 136 deletions(-) diff --git a/libmscore/articulation.cpp b/libmscore/articulation.cpp index 4537837856bd..66fa8a8807cc 100644 --- a/libmscore/articulation.cpp +++ b/libmscore/articulation.cpp @@ -494,6 +494,13 @@ bool Articulation::setProperty(P_ID propertyId, const QVariant& v) setTimeStretch(v.toDouble()); score()->fixTicks(); break; + case P_ID::USER_OFF: + setUserOff(v.toPointF()); + if (_articulationType == ArticulationType::Tenuto) { + // moving a tenuto may move slurs: + score()->setLayoutAll(true); + } + return true; default: return Element::setProperty(propertyId, v); } diff --git a/libmscore/cmd.cpp b/libmscore/cmd.cpp index 692b359c18d5..efc5b7bcc147 100644 --- a/libmscore/cmd.cpp +++ b/libmscore/cmd.cpp @@ -129,6 +129,8 @@ void Score::endCmd() } } + if (MScore::debugMode) + qDebug("===endCmd() %d", undo()->current()->childCount()); bool noUndo = undo()->current()->childCount() <= 1; if (!noUndo) setDirty(true); @@ -2037,7 +2039,7 @@ void Score::cmd(const QAction* a) Element* el = selection().element(); if (cmd == "pitch-up") { if (el && (el->type() == Element::Type::ARTICULATION || el->isText())) - undoMove(el, el->userOff() + QPointF(0.0, -MScore::nudgeStep * el->spatium())); + el->undoChangeProperty(P_ID::USER_OFF, el->userOff() + QPointF(0.0, -MScore::nudgeStep * el->spatium())); else if (el && el->type() == Element::Type::REST) cmdMoveRest(static_cast(el), MScore::Direction::UP); else if (el && el->type() == Element::Type::LYRICS) @@ -2047,7 +2049,7 @@ void Score::cmd(const QAction* a) } else if (cmd == "pitch-down") { if (el && (el->type() == Element::Type::ARTICULATION || el->isText())) - undoMove(el, el->userOff() + QPointF(0.0, MScore::nudgeStep * el->spatium())); + el->undoChangeProperty(P_ID::USER_OFF, el->userOff() + QPointF(0.0, MScore::nudgeStep * el->spatium())); else if (el && el->type() == Element::Type::REST) cmdMoveRest(static_cast(el), MScore::Direction::DOWN); else if (el && el->type() == Element::Type::LYRICS) @@ -2076,13 +2078,13 @@ void Score::cmd(const QAction* a) } else if (cmd == "pitch-up-octave") { if (el && (el->type() == Element::Type::ARTICULATION || el->isText())) - undoMove(el, el->userOff() + QPointF(0.0, -MScore::nudgeStep10 * el->spatium())); + el->undoChangeProperty(P_ID::USER_OFF, el->userOff() + QPointF(0.0, -MScore::nudgeStep10 * el->spatium())); else upDown(true, UpDownMode::OCTAVE); } else if (cmd == "pitch-down-octave") { if (el && (el->type() == Element::Type::ARTICULATION || el->isText())) - undoMove(el, el->userOff() + QPointF(0.0, MScore::nudgeStep10 * el->spatium())); + el->undoChangeProperty(P_ID::USER_OFF, el->userOff() + QPointF(0.0, MScore::nudgeStep10 * el->spatium())); else upDown(false, UpDownMode::OCTAVE); } diff --git a/libmscore/property.cpp b/libmscore/property.cpp index 08497ea9b55c..6b0924e0388b 100644 --- a/libmscore/property.cpp +++ b/libmscore/property.cpp @@ -76,7 +76,7 @@ static const PropertyData propertyList[] = { { P_ID::PLAY, false, "play", P_TYPE::BOOL }, { P_ID::TIMESIG_NOMINAL, false, 0, P_TYPE::FRACTION }, { P_ID::TIMESIG_ACTUAL, true, 0, P_TYPE::FRACTION }, - + { P_ID::NUMBER_TYPE, false, "numberType", P_TYPE::INT }, { P_ID::BRACKET_TYPE, false, "bracketType", P_TYPE::INT }, { P_ID::NORMAL_NOTES, false, "normalNotes", P_TYPE::INT }, @@ -200,6 +200,11 @@ static const PropertyData propertyList[] = { { P_ID::ANCHOR, false, "anchor", P_TYPE::INT }, + { P_ID::SLUR_UOFF1, false, "o1", P_TYPE::POINT }, + { P_ID::SLUR_UOFF2, false, "o2", P_TYPE::POINT }, + { P_ID::SLUR_UOFF3, false, "o3", P_TYPE::POINT }, + { P_ID::SLUR_UOFF4, false, "o4", P_TYPE::POINT }, + { P_ID::END, false, "", P_TYPE::INT } }; diff --git a/libmscore/property.h b/libmscore/property.h index 5deb0b667752..575f98201033 100644 --- a/libmscore/property.h +++ b/libmscore/property.h @@ -197,6 +197,11 @@ enum class P_ID : unsigned char { ANCHOR, + SLUR_UOFF1, + SLUR_UOFF2, + SLUR_UOFF3, + SLUR_UOFF4, + END }; diff --git a/libmscore/score.h b/libmscore/score.h index 8e1cd8cddc30..1b030d0a9eb7 100644 --- a/libmscore/score.h +++ b/libmscore/score.h @@ -523,7 +523,6 @@ class Score : public QObject { void undoRemoveStaff(Staff* staff, int idx); void undoInsertStaff(Staff* staff, int idx); void undoChangeInvisible(Element*, bool); - void undoMove(Element* e, const QPointF& pt); void undoChangeBracketSpan(Staff* staff, int column, int span); void undoChangeTuning(Note*, qreal); void undoChangePageFormat(PageFormat*, qreal spatium, int); diff --git a/libmscore/slur.cpp b/libmscore/slur.cpp index d4dd8772b4de..a4b30b2df5c7 100644 --- a/libmscore/slur.cpp +++ b/libmscore/slur.cpp @@ -32,6 +32,10 @@ namespace Ms { +Element* SlurTie::editEndElement; +Element* SlurTie::editStartElement; +QList SlurTie::editUps; + //--------------------------------------------------------- // SlurSegment //--------------------------------------------------------- @@ -418,14 +422,11 @@ void SlurSegment::write(Xml& xml, int no) const return; xml.stag(QString("SlurSegment no=\"%1\"").arg(no)); - if (!(ups[int(GripSlurSegment::START)].off.isNull())) - xml.tag("o1", ups[int(GripSlurSegment::START)].off); - if (!(ups[int(GripSlurSegment::BEZIER1)].off.isNull())) - xml.tag("o2", ups[int(GripSlurSegment::BEZIER1)].off); - if (!(ups[int(GripSlurSegment::BEZIER2)].off.isNull())) - xml.tag("o3", ups[int(GripSlurSegment::BEZIER2)].off); - if (!(ups[int(GripSlurSegment::END)].off.isNull())) - xml.tag("o4", ups[int(GripSlurSegment::END)].off); + + writeProperty(xml, P_ID::SLUR_UOFF1); + writeProperty(xml, P_ID::SLUR_UOFF2); + writeProperty(xml, P_ID::SLUR_UOFF3); + writeProperty(xml, P_ID::SLUR_UOFF4); Element::writeProperties(xml); xml.etag(); } @@ -1101,6 +1102,14 @@ QVariant SlurSegment::getProperty(P_ID propertyId) const case P_ID::LINE_TYPE: case P_ID::SLUR_DIRECTION: return slurTie()->getProperty(propertyId); + case P_ID::SLUR_UOFF1: + return ups[int(GripSlurSegment::START)].off; + case P_ID::SLUR_UOFF2: + return ups[int(GripSlurSegment::BEZIER1)].off; + case P_ID::SLUR_UOFF3: + return ups[int(GripSlurSegment::BEZIER2)].off; + case P_ID::SLUR_UOFF4: + return ups[int(GripSlurSegment::END)].off; default: return SpannerSegment::getProperty(propertyId); } @@ -1116,9 +1125,22 @@ bool SlurSegment::setProperty(P_ID propertyId, const QVariant& v) case P_ID::LINE_TYPE: case P_ID::SLUR_DIRECTION: return slurTie()->setProperty(propertyId, v); + case P_ID::SLUR_UOFF1: + ups[int(GripSlurSegment::START)].off = v.toPointF(); + break; + case P_ID::SLUR_UOFF2: + ups[int(GripSlurSegment::BEZIER1)].off = v.toPointF(); + break; + case P_ID::SLUR_UOFF3: + ups[int(GripSlurSegment::BEZIER2)].off = v.toPointF(); + break; + case P_ID::SLUR_UOFF4: + ups[int(GripSlurSegment::END)].off = v.toPointF(); + break; default: return SpannerSegment::setProperty(propertyId, v); } + score()->setLayoutAll(true); return true; } @@ -1132,6 +1154,11 @@ QVariant SlurSegment::propertyDefault(P_ID id) const case P_ID::LINE_TYPE: case P_ID::SLUR_DIRECTION: return slurTie()->propertyDefault(id); + case P_ID::SLUR_UOFF1: + case P_ID::SLUR_UOFF2: + case P_ID::SLUR_UOFF3: + case P_ID::SLUR_UOFF4: + return QPointF(); default: return SpannerSegment::propertyDefault(id); } @@ -1143,10 +1170,12 @@ QVariant SlurSegment::propertyDefault(P_ID id) const void SlurSegment::reset() { - score()->undoChangeProperty(this, P_ID::USER_OFF, QPointF()); - score()->undo(new ChangeSlurOffsets(this, QPointF(), QPointF(), QPointF(), QPointF())); - for (int i = 0; i < int(GripSlurSegment::GRIPS); ++i) - ups[i].off = QPointF(); + score()->undoChangeProperty(this, P_ID::USER_OFF, QPointF()); + score()->undoChangeProperty(this, P_ID::SLUR_UOFF1, QPointF()); + score()->undoChangeProperty(this, P_ID::SLUR_UOFF2, QPointF()); + score()->undoChangeProperty(this, P_ID::SLUR_UOFF3, QPointF()); + score()->undoChangeProperty(this, P_ID::SLUR_UOFF4, QPointF()); + parent()->reset(); parent()->layout(); } @@ -1461,5 +1490,86 @@ void SlurTie::fixupSegments(unsigned nsegs) } } } + +//--------------------------------------------------------- +// startEdit +//--------------------------------------------------------- + +void SlurTie::startEdit(MuseScoreView* view, const QPointF& pt) + { + Spanner::startEdit(view, pt); + + editStartElement = startElement(); + editEndElement = endElement(); + + editUps.clear(); + foreach (SpannerSegment* s, spannerSegments()) { + SlurOffsets o; + SlurSegment* ss = static_cast(s); + o.o[0] = ss->getProperty(P_ID::SLUR_UOFF1).toPointF(); + o.o[1] = ss->getProperty(P_ID::SLUR_UOFF2).toPointF(); + o.o[2] = ss->getProperty(P_ID::SLUR_UOFF3).toPointF(); + o.o[3] = ss->getProperty(P_ID::SLUR_UOFF4).toPointF(); + editUps.append(o); + } + } + +//--------------------------------------------------------- +// endEdit +//--------------------------------------------------------- + +void SlurTie::endEdit() + { + Spanner::endEdit(); + if (type() == Element::Type::SLUR) { + if ((editStartElement != startElement()) || (editEndElement != endElement())) { + // + // handle parts: + // search new start/end elements + // + for (Element* e : linkList()) { + Spanner* spanner = static_cast(e); + if (spanner == this) + score()->undo()->push1(new ChangeStartEndSpanner(this, editStartElement, editEndElement)); + else { + Element* se = 0; + Element* ee = 0; + if (startElement()) { + QList sel = startElement()->linkList(); + for (Element* e : sel) { + if (e->score() == spanner->score() && e->track() == spanner->track()) { + se = e; + break; + } + } + } + if (endElement()) { + QList sel = endElement()->linkList(); + for (Element* e : sel) { + if (e->score() == spanner->score() && e->track() == spanner->track2()) { + ee = e; + break; + } + } + } + score()->undo(new ChangeStartEndSpanner(spanner, se, ee)); + } + } + } + } + if (spannerSegments().size() != editUps.size()) { + qDebug("SlurTie::endEdit(): segment size changed %d != %d", spannerSegments().size(), editUps.size()); + return; + } + for (int i = 0; i < editUps.size(); ++i) { + SpannerSegment* ss = segments[i]; + SlurOffsets o = editUps[i]; + score()->undoPropertyChanged(ss, P_ID::SLUR_UOFF1, o.o[0]); + score()->undoPropertyChanged(ss, P_ID::SLUR_UOFF2, o.o[1]); + score()->undoPropertyChanged(ss, P_ID::SLUR_UOFF3, o.o[2]); + score()->undoPropertyChanged(ss, P_ID::SLUR_UOFF4, o.o[3]); + } + } + } diff --git a/libmscore/slur.h b/libmscore/slur.h index 5e2ddd5d5c19..5eba40442111 100644 --- a/libmscore/slur.h +++ b/libmscore/slur.h @@ -58,6 +58,10 @@ struct UP { } }; +struct SlurOffsets { + QPointF o[4]; + }; + //--------------------------------------------------------- // @@ SlurSegment /// also used for Tie @@ -68,6 +72,7 @@ class SlurSegment : public SpannerSegment { protected: struct UP ups[int(GripSlurSegment::GRIPS)]; + QPainterPath path; QPainterPath shapePath; QPointF autoAdjustOffset; @@ -115,6 +120,7 @@ class SlurSegment : public SpannerSegment { friend class Tie; friend class Slur; + friend class SlurTie; }; //------------------------------------------------------------------- @@ -131,6 +137,10 @@ class SlurTie : public Spanner { int _lineType; // 0 = solid, 1 = dotted, 2 = dashed + static Element* editStartElement; + static Element* editEndElement; + static QList editUps; + protected: bool _up; // actual direction @@ -170,6 +180,9 @@ class SlurTie : public Spanner { virtual void slurPos(SlurPos*) = 0; virtual void computeBezier(SlurSegment*, QPointF so = QPointF()) = 0; + virtual void startEdit(MuseScoreView*, const QPointF&) override; + virtual void endEdit() override; + virtual QVariant getProperty(P_ID propertyId) const; virtual bool setProperty(P_ID propertyId, const QVariant&); virtual QVariant propertyDefault(P_ID id) const; diff --git a/libmscore/spanner.cpp b/libmscore/spanner.cpp index 298c3897698b..2abb27e0da58 100644 --- a/libmscore/spanner.cpp +++ b/libmscore/spanner.cpp @@ -26,8 +26,6 @@ int Spanner::editTick2; int Spanner::editTrack2; QList Spanner::userOffsets2; QList Spanner::userOffsets; -Element* Spanner::editEndElement; -Element* Spanner::editStartElement; //--------------------------------------------------------- // SpannerSegment @@ -257,9 +255,6 @@ void Spanner::startEdit(MuseScoreView*, const QPointF&) editTick2 = _tick2; editTrack2 = _track2; - editStartElement = _startElement; - editEndElement = _endElement; - userOffsets.clear(); userOffsets2.clear(); foreach (SpannerSegment* ss, spannerSegments()) { @@ -288,57 +283,19 @@ void Spanner::endEdit() rebuild = true; } - if (type() == Element::Type::SLUR) { - if ((editStartElement != _startElement) || (editEndElement != _endElement)) { - // - // handle parts: - // search new start/end elements - // - for (Element* e : linkList()) { - Spanner* spanner = static_cast(e); - if (spanner == this) - score()->undo()->push1(new ChangeStartEndSpanner(this, editStartElement, editEndElement)); - else { - Element* se = 0; - Element* ee = 0; - if (_startElement) { - QList sel = _startElement->linkList(); - for (Element* e : sel) { - if (e->score() == spanner->score() && e->track() == spanner->track()) { - se = e; - break; - } - } - } - if (_endElement) { - QList sel = _endElement->linkList(); - for (Element* e : sel) { - if (e->score() == spanner->score() && e->track() == spanner->track2()) { - ee = e; - break; - } - } - } - score()->undo(new ChangeStartEndSpanner(spanner, se, ee)); - } - } - } - } - if (rebuild) score()->rebuildBspTree(); if (spannerSegments().size() != userOffsets2.size()) { - qDebug("SLine::endEdit(): segment size changed"); + qDebug("Spanner::endEdit(): segment size changed"); return; } -#if 0 //HACK + for (int i = 0; i < userOffsets2.size(); ++i) { SpannerSegment* ss = segments[i]; score()->undoPropertyChanged(ss, P_ID::USER_OFF, userOffsets[i]); score()->undoPropertyChanged(ss, P_ID::USER_OFF2, userOffsets2[i]); } -#endif } //--------------------------------------------------------- diff --git a/libmscore/spanner.h b/libmscore/spanner.h index 894a5bcd056a..37f39483f228 100644 --- a/libmscore/spanner.h +++ b/libmscore/spanner.h @@ -101,7 +101,6 @@ class Spanner : public Element { Q_PROPERTY(int tick2 READ tick2 WRITE setTick2) Q_PROPERTY(Ms::Spanner::Anchor anchor READ anchor WRITE setAnchor) - QList segments; Anchor _anchor = Anchor::SEGMENT; Element* _startElement = 0; Element* _endElement = 0; @@ -113,9 +112,8 @@ class Spanner : public Element { static QList userOffsets2; protected: + QList segments; static int editTick, editTick2, editTrack2; - static Element* editStartElement; - static Element* editEndElement; public: Spanner(Score* = 0); diff --git a/libmscore/undo.cpp b/libmscore/undo.cpp index 169edb70dbe4..c8b592fdecaf 100644 --- a/libmscore/undo.cpp +++ b/libmscore/undo.cpp @@ -712,15 +712,6 @@ void Score::undoInsertStaff(Staff* staff, int idx) undo(new InsertStaff(staff, idx)); } -//--------------------------------------------------------- -// undoMove -//--------------------------------------------------------- - -void Score::undoMove(Element* e, const QPointF& pt) - { - undo(new MoveElement(e, pt)); - } - //--------------------------------------------------------- // undoChangeVoltaEnding //--------------------------------------------------------- @@ -2051,19 +2042,6 @@ void ChangeSingleBarLineSpan::flip() barLine->score()->addRefresh(barLine->abbox()); // new area of this bar line needs redraw } -//--------------------------------------------------------- -// ChangeSlurOffsets -//--------------------------------------------------------- - -void ChangeSlurOffsets::flip() - { - for (int i = 0; i < 4; ++i) { - QPointF f = slur->slurOffset(i); - slur->setSlurOffset(i, off[i]); - off[i] = f; - } - } - //--------------------------------------------------------- // TransposeHarmony //--------------------------------------------------------- @@ -2189,27 +2167,6 @@ void ChangeChordRestDuration::flip() f = od; } -//--------------------------------------------------------- -// MoveElement -//--------------------------------------------------------- - -MoveElement::MoveElement(Element* e, const QPointF& o) - { - element = e; - offset = o; - } - -void MoveElement::flip() - { - QPointF po = element->userOff(); - element->score()->addRefresh(element->canvasBoundingRect()); - element->setUserOff(offset); - if (element->type() == Element::Type::REST) - element->layout(); // ledgerline could change - element->score()->addRefresh(element->canvasBoundingRect()); - offset = po; - } - //--------------------------------------------------------- // ChangeBracketSpan //--------------------------------------------------------- diff --git a/libmscore/undo.h b/libmscore/undo.h index 288533caa5c7..79d8d1c2b9b5 100644 --- a/libmscore/undo.h +++ b/libmscore/undo.h @@ -476,26 +476,6 @@ class ChangeSingleBarLineSpan : public UndoCommand { UNDO_NAME("ChangeSingleBarLineSpan") }; -//--------------------------------------------------------- -// ChangeSlurOffsets -//--------------------------------------------------------- - -class ChangeSlurOffsets : public UndoCommand { - SlurSegment* slur; - QPointF off[4]; - void flip(); - - public: - ChangeSlurOffsets(SlurSegment* s, const QPointF& o1, const QPointF& o2, - const QPointF& o3, const QPointF& o4) : slur(s) { - off[0] = o1; - off[1] = o2; - off[2] = o3; - off[3] = o4; - } - UNDO_NAME("ChangeSlurOffsets") - }; - //--------------------------------------------------------- // SigInsertTime //--------------------------------------------------------- diff --git a/mscore/dragelement.cpp b/mscore/dragelement.cpp index eeb25aa94c25..eb890b924bc8 100644 --- a/mscore/dragelement.cpp +++ b/mscore/dragelement.cpp @@ -135,9 +135,7 @@ void ScoreView::endDrag() else { foreach(Element* e, _score->selection().elements()) { e->endDrag(); - QPointF npos = e->userOff(); - e->setUserOff(e->startDragPosition()); - _score->undoMove(e, npos); + e->score()->undoPropertyChanged(e, P_ID::USER_OFF, e->startDragPosition()); } } _score->setLayoutAll(true); diff --git a/mscore/scoreview.cpp b/mscore/scoreview.cpp index 87d79dd086c5..c9275822c437 100644 --- a/mscore/scoreview.cpp +++ b/mscore/scoreview.cpp @@ -2619,13 +2619,13 @@ void ScoreView::cmd(const QAction* a) if (el && (el->isText())) { score()->startCmd(); if (cmd == "prev-chord") - score()->undoMove(el, el->userOff() - QPointF (MScore::nudgeStep * el->spatium(), 0.0)); + el->undoChangeProperty(P_ID::USER_OFF, el->userOff() - QPointF (MScore::nudgeStep * el->spatium(), 0.0)); else if (cmd == "next-chord") - score()->undoMove(el, el->userOff() + QPointF (MScore::nudgeStep * el->spatium(), 0.0)); + el->undoChangeProperty(P_ID::USER_OFF, el->userOff() + QPointF (MScore::nudgeStep * el->spatium(), 0.0)); else if (cmd == "prev-measure") - score()->undoMove(el, el->userOff() - QPointF (MScore::nudgeStep10 * el->spatium(), 0.0)); + el->undoChangeProperty(P_ID::USER_OFF, el->userOff() - QPointF (MScore::nudgeStep10 * el->spatium(), 0.0)); else if (cmd == "next-measure") - score()->undoMove(el, el->userOff() + QPointF (MScore::nudgeStep10 * el->spatium(), 0.0)); + el->undoChangeProperty(P_ID::USER_OFF, el->userOff() + QPointF (MScore::nudgeStep10 * el->spatium(), 0.0)); score()->endCmd(); } else {