Skip to content

Commit ead884c

Browse files
committed
feat: expose API for changing part instruments
1 parent 63e8527 commit ead884c

File tree

2 files changed

+57
-0
lines changed

2 files changed

+57
-0
lines changed

src/engraving/api/v1/score.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@
3232
#include "editing/editsystemlocks.h"
3333
#include "types/typesconv.h"
3434

35+
// notation
36+
#include "notation/inotation.h"
37+
#include "notation/inotationparts.h"
38+
#include "notation/notationtypes.h"
39+
3540
// api
3641
#include "apistructs.h"
3742
#include "cursor.h"
@@ -158,6 +163,49 @@ void Score::appendPartByMusicXmlId(const QString& instrumentMusicXmlId)
158163
score()->appendPart(t);
159164
}
160165

166+
//---------------------------------------------------------
167+
// Score::replaceInstrument
168+
//---------------------------------------------------------
169+
170+
void Score::replaceInstrument(apiv1::Part* part, const QString& instrumentId)
171+
{
172+
if (!part) {
173+
LOGW("replaceInstrument: part is null");
174+
return;
175+
}
176+
177+
const InstrumentTemplate* t = searchTemplate(instrumentId);
178+
if (!t) {
179+
LOGW("replaceInstrument: <%s> not found", qPrintable(instrumentId));
180+
return;
181+
}
182+
183+
// Get the notation interface to access INotationParts
184+
mu::notation::INotationPtr notationPtr = notation();
185+
if (!notationPtr) {
186+
LOGW("replaceInstrument: notation is null");
187+
return;
188+
}
189+
190+
mu::notation::INotationPartsPtr parts = notationPtr->parts();
191+
if (!parts) {
192+
LOGW("replaceInstrument: notation parts is null");
193+
return;
194+
}
195+
196+
// Create InstrumentKey for the main instrument of the part
197+
mu::notation::InstrumentKey instrumentKey;
198+
instrumentKey.partId = muse::ID(part->part()->id());
199+
instrumentKey.instrumentId = muse::String::fromQString(part->part()->instrumentId());
200+
instrumentKey.tick = mu::engraving::Fraction(0, 1); // Main instrument at tick 0
201+
202+
// Create the new Instrument from the template
203+
mu::engraving::Instrument newInstrument = mu::engraving::Instrument::fromTemplate(t);
204+
205+
// Call replaceInstrument through the notation layer
206+
parts->replaceInstrument(instrumentKey, newInstrument);
207+
}
208+
161209
//---------------------------------------------------------
162210
// Score::firstSegment
163211
//---------------------------------------------------------

src/engraving/api/v1/score.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,15 @@ class Score : public apiv1::ScoreElement, public muse::Injectable
236236
/// \since MuseScore 3.5
237237
Q_INVOKABLE void appendPartByMusicXmlId(const QString& instrumentMusicXmlId);
238238

239+
/// Replaces the instrument for a given part with a new instrument.
240+
/// This changes the instrument definition including its name, clef, and sound.
241+
/// \param part - The Part object whose instrument should be replaced.
242+
/// \param instrumentId - ID of the new instrument, as listed in
243+
/// [`instruments.xml`](https://github.com/musescore/MuseScore/blob/3.x/share/instruments/instruments.xml)
244+
/// file.
245+
/// \since MuseScore 4.7
246+
Q_INVOKABLE void replaceInstrument(apiv1::Part* part, const QString& instrumentId);
247+
239248
/// Appends a number of measures to this score.
240249
Q_INVOKABLE void appendMeasures(int n) { score()->appendMeasures(n); }
241250
Q_INVOKABLE void addText(const QString& type, const QString& text);

0 commit comments

Comments
 (0)