diff --git a/libmscore/slur.cpp b/libmscore/slur.cpp index f82845bd4a9f..7a008da16df7 100644 --- a/libmscore/slur.cpp +++ b/libmscore/slur.cpp @@ -184,10 +184,7 @@ bool SlurSegment::edit(MuseScoreView* viewer, int curGrip, int key, Qt::Keyboard int endTrack = part->endTrack(); cr = searchCR(e->segment(), startTrack, endTrack); } - if (cr && cr != e1 -// && ((curGrip == int(GripSlurSegment::END) && cr->tick() > sl->tick()) -// || (curGrip == int(GripSlurSegment::START) && cr->tick() < sl->tick2() )) - ) + if (cr && cr != e1) changeAnchor(viewer, curGrip, cr); return true; } diff --git a/libmscore/spanner.cpp b/libmscore/spanner.cpp index 6c5364648bb5..6ebd35fb2c06 100644 --- a/libmscore/spanner.cpp +++ b/libmscore/spanner.cpp @@ -17,6 +17,7 @@ #include "chord.h" #include "segment.h" #include "measure.h" +#include "undo.h" namespace Ms { @@ -25,6 +26,8 @@ int Spanner::editTick2; int Spanner::editTrack2; QList Spanner::userOffsets2; QList Spanner::userOffsets; +Element* Spanner::editEndElement; +Element* Spanner::editStartElement; //--------------------------------------------------------- // SpannerSegment @@ -251,10 +254,13 @@ void Spanner::setScore(Score* s) void Spanner::startEdit(MuseScoreView*, const QPointF&) { - editTick = _tick; - editTick2 = _tick2; + editTick = _tick; + editTick2 = _tick2; editTrack2 = _track2; + editStartElement = _startElement; + editEndElement = _endElement; + userOffsets.clear(); userOffsets2.clear(); foreach (SpannerSegment* ss, spannerSegments()) { @@ -283,6 +289,43 @@ 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(); diff --git a/libmscore/spanner.h b/libmscore/spanner.h index 22a2c8375930..3a5f8c0f8a79 100644 --- a/libmscore/spanner.h +++ b/libmscore/spanner.h @@ -115,6 +115,8 @@ class Spanner : public Element { protected: 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 3a0d7f03d059..84ba7dfe4b1b 100644 --- a/libmscore/undo.cpp +++ b/libmscore/undo.cpp @@ -880,12 +880,6 @@ void Score::undoAddElement(Element* element) #endif ne->score()->updateNotes(); } -/* else if (ne->type() == Element::Type::SLUR) { - Slur* slur = static_cast(ne); - slur->setStartElement(e); - slur->setEndElement(e->parent()); - } - */ } return; } @@ -1020,13 +1014,39 @@ void Score::undoAddElement(Element* element) || element->type() == Element::Type::TEXTLINE || element->type() == Element::Type::PEDAL || element->type() == Element::Type::VOLTA) { - // ne->setParent(0); ??? - Spanner* nsp = static_cast(ne); - Spanner* sp = static_cast(element); + Spanner* sp = static_cast(element); + Spanner* nsp = static_cast(ne); int staffIdx1 = sp->track() / VOICES; int staffIdx2 = sp->track2() / VOICES; - int diff = staffIdx2 - staffIdx1; + int diff = staffIdx2 - staffIdx1; nsp->setTrack2((staffIdx + diff) * VOICES + (sp->track2() % VOICES)); + + // determine start/end element for slurs + // this is only necessary if start/end element is + // a grace note, otherwise the element can be set to zero + // and will later be calculated from tick/track values + // + if (element->type() == Element::Type::SLUR && sp != nsp) { + if (sp->startElement()) { + QList sel = sp->startElement()->linkList(); + for (Element* e : sel) { + if (e->score() == nsp->score() && e->track() == nsp->track()) { + nsp->setStartElement(e); + break; + } + } + } + if (sp->endElement()) { + QList eel = sp->endElement()->linkList(); + for (Element* e : eel) { + if (e->score() == nsp->score() && e->track() == nsp->track2()) { + nsp->setEndElement(e); + break; + } + } + } + } + undo(new AddElement(nsp)); } else if (element->type() == Element::Type::TREMOLO && static_cast(element)->twoNotes()) { @@ -3396,5 +3416,20 @@ void Unlink::redo() Q_ASSERT(le); e->unlink(); } + +//--------------------------------------------------------- +// ChangeStartEndSpanner::flip +//--------------------------------------------------------- + +void ChangeStartEndSpanner::flip() + { + Element* s = spanner->startElement(); + Element* e = spanner->endElement(); + spanner->setStartElement(start); + spanner->setEndElement(end); + start = s; + end = e; + } + } diff --git a/libmscore/undo.h b/libmscore/undo.h index 1f9e4037fa1b..048c3d045985 100644 --- a/libmscore/undo.h +++ b/libmscore/undo.h @@ -1420,6 +1420,22 @@ class Unlink : public UndoCommand { virtual void redo(); }; +//--------------------------------------------------------- +// ChangeStartEndSpanner +//--------------------------------------------------------- + +class ChangeStartEndSpanner : public UndoCommand { + Spanner* spanner; + Element* start; + Element* end; + + void flip(); + + public: + ChangeStartEndSpanner(Spanner* sp, Element*s, Element*e) : spanner(sp), start(s), end(e) {} + }; + + } // namespace Ms #endif diff --git a/mscore/scoreview.cpp b/mscore/scoreview.cpp index 58545c656c9f..516ed5c2077a 100644 --- a/mscore/scoreview.cpp +++ b/mscore/scoreview.cpp @@ -4030,11 +4030,7 @@ void ScoreView::cmdAddSlur(Note* firstNote, Note* lastNote) { _score->startCmd(); ChordRest* cr1 = firstNote->chord(); - ChordRest* cr2; - if (cr1->isGrace()) - cr2 = static_cast(cr1->parent()); - else - cr2 = lastNote ? lastNote->chord() : nextChordRest(cr1); + ChordRest* cr2 = lastNote ? lastNote->chord() : nextChordRest(cr1); if (cr2 == 0) cr2 = cr1;