musescore / musescore/MuseScore

Plugin API: Score.appendPart() does not apply tablature staff type from instrument template

Open Beginner friendly
#33,820 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C++
Stars
15.1k
Forks
3.3k
Avg merge
2d 2h
Merged PRs (30d)
91

Description

Summary

Score::appendPart(const InstrumentTemplate*) — the function backing the plugin API's Score.appendPart(id) and Score.appendPartByMusicXmlId(id) — does not apply the template's staffTypePreset. As a result, calling appendPart("guitar-nylon-tablature") from a plugin produces a standard 5-line staff instead of a tablature staff. Same issue affects every instrument whose template carries a non-default StaffType preset (all TAB variants, etc.).

Repro (from any plugin)

curScore.startCmd()
curScore.appendPart("guitar-nylon-tablature")
curScore.endCmd()

Expected: a TAB staff (6 lines, tab clef, fret-number rendering).
Actual: a standard 5-line staff with treble clef.

Root cause

The function lives at src/engraving/dom/score.cpp:4371. In current HEAD it reads:

Staff* staff = Factory::createStaff(part);
StaffType* stt = staff->staffType(Fraction(0, 1));
staff->init(t, stt, int(i));

Factory::createStaff runs Staff::Staff(Part*), which calls initFromStaffType(0) — assigning the default STANDARD preset. So staff->staffType(0) returns a pointer to that default standard StaffType.

That pointer is then handed to Staff::init as its second argument:

// staff.cpp:1372
const StaffType* pst = staffType ? staffType : t->staffTypePreset;

Because staffType is non-null, t->staffTypePreset is never consulted — the staff stays standard regardless of what the instrument template requested.

This is a follow-up bug to #29478 ("Set default clefs when creating parts", commit 451b451bd8). That PR correctly replaced the old hand-rolled body of appendPart with a delegation to Staff::init, but the vestigial stt local left over from the previous body got threaded into the new init call.

Scope

  • Score::appendPart(const InstrumentTemplate*) is only invoked by the plugin API (src/engraving/api/v1/score.cpp:139, 155). The Instruments-panel "Add instrument" flow uses a different path (Excerpt::cloneStaff) and is unaffected.
  • Bug has been latent in some form since 2012 (commit dc5fda47f3, Werner Schweer) — the original hand-rolled body never applied the preset either. Plugin authors have been working around it by asking users to add the tablature instrument manually via the Instruments panel.

Proposed fix

One-line change: pass nullptr instead of stt, letting Staff::init fall through to t->staffTypePreset. Happy to send a PR with the fix and regression tests if maintainers agree on the approach.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Read src/engraving/dom/score.cpp:4371 and the Staff::init logic in staff.cpp:1372, then trace the plugin entry points in src/engraving/api/v1/score.cpp. Verify appendPart for guitar-nylon-tablature and other non-default staff presets produces the template's staff type, with regression coverage for the plugin API behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
api, backend
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
76/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.