Skip to content

Expose remaining Part/Staff editing methods to Plugin API#32636

Merged
RomanPudashkin merged 6 commits intomusescore:masterfrom
manolo:pr_remaining_api_methods
Mar 30, 2026
Merged

Expose remaining Part/Staff editing methods to Plugin API#32636
RomanPudashkin merged 6 commits intomusescore:masterfrom
manolo:pr_remaining_api_methods

Conversation

@manolo
Copy link
Copy Markdown
Contributor

@manolo manolo commented Mar 16, 2026

Related to: #31201
Follow-up to: #31205, #32185

Summary

This is the third and final PR for exposing NotationParts methods to the Plugin API (issue #31201). It implements the 7 methods that were deferred in PR #32185 due to prerequisite work.

All new methods follow the established pattern: shared static methods in EditPart (used by both the Plugin API and NotationParts), with Q_INVOKABLE wrappers on the Score API class. NotationParts is refactored to delegate to EditPart, eliminating logic duplication.

Changes

Commit 1: appendStaff and appendLinkedStaff

  • appendStaff(destinationPart) : Creates and appends a new default staff to a part, returns the new staff
  • appendLinkedStaff(sourceStaff, destinationPart) : Creates a staff linked to a source staff, appends it to a part, returns the new staff
  • Private helper doAppendStaff extracted from NotationParts for shared use

Commit 2: setVoiceVisible

  • setVoiceVisible(staff, voiceIndex, visible) : Shows or hides a voice in an excerpt score. Returns false if called on a main score (excerpt only limitation)
  • Refactors NotationParts::setVoiceVisible to delegate to EditPart

Commit 3: replaceDrumset

  • replaceDrumset(part, drumset) : Applies a modified drumset to all matching instruments in a part (undoable)
  • Instrument::cloneDrumset() : Creates a writable copy of an instrument's drumset
  • Drumset individual setters for modifying cloned drumsets: setName, setNoteHead, setLine, setVoice, setStemDirection, setShortcut
  • Drumset ownership model (m_owned flag) for safe lifecycle of cloned drumsets
  • Refactors NotationParts::replaceDrumset undoable path to delegate to EditPart

Commit 4: insertPart and replacePart

  • insertPart(instrumentId, index) : Creates a new part from an instrument template and inserts it at the given index
  • replacePart(part, instrumentId) : Replaces an existing part with a new one created from an instrument template

Commit 5: setScoreOrder

  • setScoreOrder(orderId) : Sets the score order (e.g. "orchestral", "marching-band") which controls part ordering and bracket/barline layout
  • Refactors NotationParts::doSetScoreOrder to delegate to EditPart

Implementation checklist

Completed in PR #31205:

  • replaceInstrument(part, instrumentId)

Completed in PR #32185:

  • setPartVisible(part, visible)
  • setPartSharpFlat(part, sharpFlat)
  • setInstrumentName(part, tick, name)
  • setInstrumentAbbreviature(part, tick, abbreviature)
  • setStaffType(staff, staffTypeId)
  • removeParts(parts)
  • removeStaves(staves)
  • moveParts(sourceParts, destinationPart, mode)
  • moveStaves(sourceStaves, destinationStaff, mode)
  • addSystemObjects(staves)
  • removeSystemObjects(staves)
  • moveSystemObjects(sourceStaff, destinationStaff)
  • Staff writable properties via Pid (visible, cutaway, hideSystemBarLine, mergeMatchingRests, reflectTranspositionInLinkedTab)

Completed in this PR:

  • appendStaff(destinationPart)
  • appendLinkedStaff(sourceStaff, destinationPart)
  • setVoiceVisible(staff, voiceIndex, visible)
  • replaceDrumset(part, drumset)
  • insertPart(instrumentId, index)
  • replacePart(part, instrumentId)
  • setScoreOrder(orderId)

Usage examples

curScore.startCmd("Append staff");

// Append a new staff to the first part
var newStaff = curScore.appendStaff(curScore.parts[0]);

// Append a linked staff (content mirrors the source)
var linked = curScore.appendLinkedStaff(curScore.staves[0], curScore.parts[0]);

curScore.endCmd();
curScore.startCmd("Edit drumset");

// Clone the drumset, modify entries, and apply
var instrument = curScore.parts[0].instrumentAtTick(0);
var drumset = instrument.cloneDrumset();
drumset.setName(36, "Kick Drum");
drumset.setLine(36, 4);
drumset.setVoice(36, 1);
drumset.setStemDirection(36, 1);
curScore.replaceDrumset(curScore.parts[0], drumset);

curScore.endCmd();
curScore.startCmd("Insert and replace parts");

// Insert a flute at position 0
curScore.insertPart("flute", 0);

// Replace the last part with a cello
var lastPart = curScore.parts[curScore.parts.length - 1];
curScore.replacePart(lastPart, "cello");

// Set orchestral score order
curScore.setScoreOrder("orchestral");

curScore.endCmd();

  • I signed the CLA
  • The title of the PR describes the problem it addresses
  • Each commit's message describes its purpose and effects, and references the issue it resolves
  • If changes are extensive, there is a sequence of easily reviewable commits
  • The code in the PR follows the coding rules
  • There are no unnecessary changes
  • The code compiles and runs on my machine, preferably after each commit individually
  • I created a unit test or vtest to verify the changes I made (if applicable)

manolo added 5 commits March 9, 2026 20:32
Add EditPart::appendStaff and EditPart::appendLinkedStaff static methods
that create and append staves to a part, with proper key signature
adjustment and bracket/barline updates. Expose both methods as
Q_INVOKABLE on apiv1::Score with null checks and LOGW. Add tests for
dom level operations with undo/redo and API wrapper verification.
Add EditPart::setVoiceVisible static method that delegates to
Excerpt::setVoiceVisible with proper excerpt and canDisableVoice
checks. Refactor NotationParts::setVoiceVisible to use the new
shared method. Expose as Q_INVOKABLE on apiv1::Score. Add tests
verifying it returns false on main scores (excerpt only).
Add EditPart::replaceDrumset static method that applies ChangeDrumset
undo commands for all matching instruments in a part. Add Drumset
ownership model (m_owned flag) to the API wrapper for safe clone
lifecycle, Drumset::setDrum for modifying entries, and
Instrument::cloneDrumset for creating modifiable copies. Refactor
NotationParts::replaceDrumset undoable path to delegate to EditPart.
Add tests for dom level drumset replacement with undo and API workflow.
Add EditPart::insertPart that creates a Part from an InstrumentTemplate
with proper staff initialization and MIDI mapping rebuild, and
EditPart::replacePart that removes the old part and inserts a new one
at the same index. Expose both as Q_INVOKABLE on apiv1::Score with
instrumentId string lookup via searchTemplate. Add tests for dom level
operations with undo/redo and API wrapper verification.
Add EditPart::setScoreOrder static method that applies ChangeScoreOrder
undo command and updates brackets/barlines. Refactor
NotationParts::doSetScoreOrder to delegate to EditPart. Expose as
Q_INVOKABLE on apiv1::Score with orderId string lookup via the global
instrumentOrders vector. Add tests for dom level score order change
with undo/redo and API wrapper verification.
Replace manual pitch range checks with IF_ASSERT_FAILED macro
and DRUM_INSTRUMENTS constant in all Drumset setters,
as suggested in PR review.
@DmitryArefiev
Copy link
Copy Markdown
Contributor

Tested Layout (Instruments) panel on Win10. No regressions found

@RomanPudashkin RomanPudashkin merged commit 5247ebc into musescore:master Mar 30, 2026
12 checks passed
@github-project-automation github-project-automation bot moved this to Needs porting in MuseScore Studio 4.7 Mar 30, 2026
@Jojo-Schmitz
Copy link
Copy Markdown
Contributor

Won't easily git cherry-pick into the 4.7 branch

RomanPudashkin added a commit to RomanPudashkin/MuseScore that referenced this pull request Apr 7, 2026
Expose remaining Part/Staff editing methods to Plugin API
@RomanPudashkin RomanPudashkin mentioned this pull request Apr 7, 2026
RomanPudashkin added a commit to RomanPudashkin/MuseScore that referenced this pull request Apr 7, 2026
Expose remaining Part/Staff editing methods to Plugin API
RomanPudashkin added a commit to RomanPudashkin/MuseScore that referenced this pull request Apr 7, 2026
Expose remaining Part/Staff editing methods to Plugin API
@RomanPudashkin RomanPudashkin moved this from Needs porting to Done in MuseScore Studio 4.7 Apr 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants