Skip to content

Commit

Permalink
fix #251436: plugins: support more element types in Cursor, add sanit…
Browse files Browse the repository at this point in the history
…y checks for add() argument
  • Loading branch information
dmitrio95 committed Oct 2, 2019
1 parent 52f744e commit c77d904
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 20 deletions.
67 changes: 57 additions & 10 deletions mscore/plugin/api/cursor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,11 +166,16 @@ bool Cursor::nextMeasure()

void Cursor::add(Element* wrapped)
{
Ms::Element* s = wrapped->element();
Ms::Element* s = wrapped ? wrapped->element() : nullptr;
if (!_segment || !s)
return;

// TODO: check that the previous ownership was PLUGIN
// Ensure that the object has the expected ownership
if (wrapped->ownership() == Ownership::SCORE) {
qWarning("Chord::add: Cannot add this element. The element is already part of the score.");
return; // Don't allow operation.
}

wrapped->setOwnership(Ownership::SCORE);
s->setTrack(_track);
s->setParent(_segment);
Expand All @@ -190,15 +195,48 @@ void Cursor::add(Element* wrapped)
_segment = m->first(_filter);
nextInTrack();
}
else if (s->type() == ElementType::LAYOUT_BREAK) {
Ms::Measure* m = _segment->measure();
s->setParent(m);
_score->undoAddElement(s);
}
else {
_score->undoAddElement(s);
switch (s->type()) {
case ElementType::MEASURE_NUMBER:
case ElementType::SPACER:
case ElementType::JUMP:
case ElementType::MARKER:
case ElementType::HBOX:
case ElementType::STAFFTYPE_CHANGE:
case ElementType::LAYOUT_BREAK: {
Ms::Measure* m = _segment->measure();
s->setParent(m);
_score->undoAddElement(s);
break;
}

case ElementType::NOTE:
case ElementType::ARPEGGIO:
case ElementType::TREMOLO:
case ElementType::CHORDLINE:
case ElementType::ARTICULATION: {
Ms::Element* curElement = currentElement();
if (curElement->isChord()) {
// call Chord::addInternal() (i.e. do the same as a call to Chord.add())
Chord::addInternal(toChord(curElement), s);
}
break;
}

case ElementType::LYRICS: {
Ms::Element* curElement = currentElement();
if (curElement->isChordRest()) {
s->setParent(curElement);
_score->undoAddElement(s);
}
break;
}

default:
_score->undoAddElement(s);
break;
}
}
_score->setLayoutAll();
}

//---------------------------------------------------------
Expand Down Expand Up @@ -265,6 +303,15 @@ qreal Cursor::tempo()
return _score->tempo(Fraction::fromTicks(tick()));
}

//---------------------------------------------------------
// currentElement
//---------------------------------------------------------

Ms::Element* Cursor::currentElement() const
{
return _segment && _segment->element(_track) ? _segment->element(_track) : nullptr;
}

//---------------------------------------------------------
// segment
//---------------------------------------------------------
Expand All @@ -280,7 +327,7 @@ Segment* Cursor::segment() const

Element* Cursor::element() const
{
Ms::Element* e = _segment && _segment->element(_track) ? _segment->element(_track) : nullptr;
Ms::Element* e = currentElement();
if (!e)
return nullptr;
return wrap(e, Ownership::SCORE);
Expand Down
1 change: 1 addition & 0 deletions mscore/plugin/api/cursor.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ class Cursor : public QObject {
// utility methods
void nextInTrack();
void setScore(Ms::Score* s);
Ms::Element* currentElement() const;

public:
/// \cond MS_INTERNAL
Expand Down
30 changes: 20 additions & 10 deletions mscore/plugin/api/elements.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ void Chord::setPlayEventType(Ms::PlayEventType v)

void Chord::add(Ms::PluginAPI::Element* wrapped)
{
Ms::Element* s = wrapped->element();
Ms::Element* s = wrapped ? wrapped->element() : nullptr;
if (s)
{
// Ensure that the object has the expected ownership
Expand All @@ -100,16 +100,26 @@ void Chord::add(Ms::PluginAPI::Element* wrapped)
}
// Score now owns the object.
wrapped->setOwnership(Ownership::SCORE);
// Provide parentage for element.
s->setParent(chord());
// If a note, ensure the element has proper Tpc values. (Will crash otherwise)
if (s->isNote()) {
s->setTrack(chord()->track());
toNote(s)->setTpcFromPitch();
}
// Create undo op and add the element.
chord()->score()->undoAddElement(s);

addInternal(chord(), s);
}
}

//---------------------------------------------------------
// Chord::addInternal
//---------------------------------------------------------

void Chord::addInternal(Ms::Chord* chord, Ms::Element* s)
{
// Provide parentage for element.
s->setParent(chord);
// If a note, ensure the element has proper Tpc values. (Will crash otherwise)
if (s->isNote()) {
s->setTrack(chord->track());
toNote(s)->setTpcFromPitch();
}
// Create undo op and add the element.
chord->score()->undoAddElement(s);
}

//---------------------------------------------------------
Expand Down
2 changes: 2 additions & 0 deletions mscore/plugin/api/elements.h
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,8 @@ class Chord : public Element {
Ms::NoteType noteType() { return chord()->noteType(); }
Ms::PlayEventType playEventType() { return chord()->playEventType(); }
void setPlayEventType(Ms::PlayEventType v);

static void addInternal(Ms::Chord* chord, Ms::Element* el);
/// \endcond

/// Add to a chord's elements.
Expand Down

0 comments on commit c77d904

Please sign in to comment.