Editing parts from plugins

• Oct 9, 2019 - 17:39
Reported version
3.2
Type
Plugins
Frequency
Once
Severity
S4 - Minor
Reproducibility
Always
Status
active
Regression
No
Workaround
No
Project

Coming from this comment.

When you create an element from qml (using the newElement() method) the element's score property is set to the current score, and is not editable after. So when you try to add the element to any other score using cursor.add, the element is added to the other score, but it's score property still refers to the score.

I see 3 way of dealing with this:
- Allowing READ and WRITE of the element's score property from QML
- Changing the newElement method as described there
- Changing cursor::add method: After this line, add something like s.setScore(_score)

btw, should lines 185 to 197 be refactored into the switch case


Comments

Type Functional Plugins

Sorry, I don't quite understand from the description what this issue is about. Is this about being able to edit excerpts from a plugin? If so, this should be totally possible by finding those excerpt scores viaScore.excerpts property. If you want to operate on that property with a Cursor API, just call score.newCursor() on a corresponding score object, it is not mandatory that exactly curScore should be used there. If you need to copy elements between scores you should probably obtain an element's copy via element.clone() first. Does this cover what is requested here, or is this issue about something else?

The simplest way to show this would be to ask you to run this plugin on the score in that same repo (ExportBreaksToPartPluginTestFile.mscz)
You will see that it will work: breaks will be copied to the parts. Unfortunately, if you go to the parts and click on a break, it should do something really strange: it shows the masterScore...

How it currently is:

Element* PluginAPI::newElement(int elementType)
      {
      Ms::Score* score = msc()->currentScore();
      if (!score)
            return nullptr;
      if (elementType <= int(ElementType::INVALID) || elementType >= int(ElementType::MAXTYPE)) {
            qWarning("PluginAPI::newElement: Wrong type ID: %d", elementType);
            return nullptr;
            }
      const ElementType type = ElementType(elementType);
      Ms::Element* e = Ms::Element::create(type, score);
      return wrap(e, Ownership::PLUGIN);
      }

How it could be:

Element* PluginAPI::newElement(int elementType, Ms::Score* score)
      {
      if (!score)
            return nullptr;
      if (elementType <= int(ElementType::INVALID) || elementType >= int(ElementType::MAXTYPE)) {
            qWarning("PluginAPI::newElement: Wrong type ID: %d", elementType);
            return nullptr;
            }
      const ElementType type = ElementType(elementType);
      Ms::Element* e = Ms::Element::create(type, score);
      return wrap(e, Ownership::PLUGIN);
      }

Ah, so the added elements still think that they belong to a different score. Then this is an issue indeed. I would probably resolve it though by setting a correct score in Cursor.add() (and probably Chord.add()) method. It seems logical that the elements added to some score should automatically belong to it without requiring extra explicit actions from a user (in this case, from a plugin developer).