===================================================== MuseScore Scripting Interface ===================================================== MuseScore supports plugin extensions in ECMAScript code (ECMA-262 aka "Java Script"). A plugin extension is a file with the file extension ".js". All extensions in the plugins directory are registered by MuseScore on startup. The linux plugin directory is usually located at $install-path$/museScore-0.9/plugins. On Windows you can find the plugins at ""install-path"\MuseScore 0.9\plugins". A MuseScore plugin script has access to the whole Qt Library, so it is possible to create complete guis. ===================================================== Compatibility ===================================================== The script interface is defined by two numbers, the majorVersion and the minorVersion. A script written for a different majorVersion than the current MuseScore script version may not run at all. Higher minor versions are supposed to be backward compatible. The majorVersion will be increased if the script interface changes in an incompatible way. The minorVersion will be increased if the interface is only extended. ===================================================== Debugging ===================================================== A script debugger can be enabled in Menu "Help". ===================================================== Overall structure of a MuseScore scripting plugin. ===================================================== Example of a "no operation" plugin: ----------------begin code----------------------- function init() {} function run() {} function close() {} var mscorePlugin = { majorVersion: 1, minorVersion: 1, menu: 'Plugins.test', init: init, run: run, onClose: close }; ----------------end code----------------------- The global object "mscorePlugin" defines the environment of the plugin. The variable "menu" creates a menu entry in MuseScore which triggers execution of the plugin. The test plugin above creates an entry "test" in the menu "Plugins". The syntax "entry:test" puts the new menu entry "test" before the existing entry "entry". Not existing submenus are automatically created. Dots are used as separators and must escaped with "\" if they are part of a string. "init" defines a function, which is called on MuseScore startup, when the plugins are registered. The "run" function is executed, when the user activates the "test" menu entry. The "onClose" is executed when MuseScore quits. The majorVersion and minorVersion properties are optional. If present, MuseScore checks against the current used interface version and warns of any incompatibility. ===================================================== Bindings to internal MuseScore data ===================================================== Note: (ro) stands for read-only. Objects ===================================== MuseScore this is the main application window Functions: QMenu* fileMenu() returns the file menu entry registerPlugin(QAction*) Registers the current plugin with QAction. Has to be called in the init() function of a plugin if no "menu" is defined. Score represents a complete score A new score can be created with: var a = new Score(); The new score is appended to mscores list of scores. Properties: name string file name title string title text on score subtitle string subtitle text on score composer string composer text on score poet string poet text on score staves integer number of staves (ro) duration integer total score duration in seconds (ro) pages integer number of pages (ro) measures integer number of actual measures (ro) parts integer number of parts (ro) hasLyrics bool true if a lyric element is found in the core (ro) hasHarmonies bool true if a valid chordname is found (ro) keysig integer key signature at the beginning (ro) -7 to 7 or undefined for custom signature pageFormat PageFormat the page format associated to this score Functions: bool save(string path, string type) Write score into file 'path'. "type" is the file extension and determines the type of file: "mscz", "mscx", "xml", "mxl", "mid", "pdf", "ps", "png", "svg", "ly", "wav", "flac", "ogg" Note all types may be available. bool save(string path, string type, string soundfontPath) For soundfile output ("wav", "flac", "ogg") the soundfont to be used can be specified as an additional parameter. bool save(string path, "png", boolean screenshot, boolean transparent, double dpi, boolean grayscale) Saving into a PNG file can have additional parameters setExpandRepeat(bool) appendPart(string partname) Append a new part to the score. "partname" refers to an instrument name in the file instruments.xml. The part will be initialized from the named instrument in this file. If "partname" is empty, a default part will be appended. appendMeasure(integer n) append "n" measure to score startUndo() start undoable operations endUndo() end undoable operations Part part(int i) part object at index i Cursor create: var a = new Cursor(Score score); var a = new Cursor(Score score, bool expandRepeat); Properties: staff integer voice integer pageNumber integer (ro) Fuctions: rewind() position cursor to staff/voice goToSelectionStart() position to start of selection, voice will be 0 goToSelectionEnd() position to end of selection, voice will be 0 next() goto next chord/rest nextMeasure() goto first chord/rest in next measure isChord() return true if cursor points to a chord chord() return chord at current position isRest() return true if cursor points to a rest rest() return rest at current position measure() return measure at current position putStaffText(Text) add staff text at cursor position eos() return true if at end of score add(Chord) add(Rest) measure() return the current measure next() go to next chord/rest nextMeasure() go to first chord/rest of next measure time() double current score time in ms tick() integer current score tick pos() QPointF position Chord create: var a = new Chord() var a = new Chord(Score) Properties: tickLen integer notes integer (ro) number of notes in chord type integer (ro) Note type 0 - NORMAL 1 - ACCIACCATURA 2 - APPOGGIATURA 3 - GRACE4 4 - GRACE16 5 - GRACE32 Functions: topNote() note(integer n) return note at index n; notes are sorted to pitch addNote(Note) removeNote(integer n) remove note at index n addHarmony(Harmony) Rest create: var a = new Rest() var a = new Rest(Score) Properties: tickLen integer Functions: addHarmony(Harmony) Note create: var a = new Note() var a = new Note(Score) Properties: pitch integer midi pitch value of note name string name of note tpc value (read only) color QColor notehead color tuning double note tuning tpc integer tonal pitch class visible boolean tied enum 0 no tie, 1 forward, 2 backward, 3 forw.+backw. userAccidental integer Text create: var a = new Text(score); Properties: text string the displayed text defaultFont QFont color QColor text foreground color Harmony create: var a = new Harmony(); Properties: id integer chord id root integer tonal pitch class of root base integer tonal pitch class of base Style HarmonyInfo Measure Properties: lineBreak bool break the system after this measure pageNumber integer number of the page where the measure is drawn (ro) Functions: QRectF boundingRect() bounding box (ro) QPointF pos() position (ro) Part Properties: longName string long name of the part (ro) shortName string short name of the part (ro) midiProgram integer midi program of the part (ro) midiChannel integer midi channel of the part (ro) staves integer number of staves in the part (ro) PageFormat Properties: landscape bool true if the score is in landscape orientation (ro) twosided bool true if the score is two sided (ro) width double page width in mm (ro) height double page height in mm (ro) Global Variables ===================================== mscore MuseScore This is the main application window pluginPath string path of current active plugin This path can be used find additional data associated with this plugin. curScore Score current active Score curCursor Cursor division integer number of midi ticks for 1/4 note mscoreVersion integer complete version number: MMmmuu (major/minor/update) mscoreMajorVersion integer mscoreMinorVersion integer mscoreUpdateVersion integer majorVersion integer interface major version of the currently running interpreter minorVersion integer interface minor version number ===================================================== Translation ===================================================== See: http://doc.trolltech.com/4.6/scripting.html#internationalization To translate a plugin, you need to use : qsTr() for all your "quoted text" For the menu item use : QT_TR_NOOP("Plugins.MyMenuItem") Then create a directory "translations" in the plugin directory. You need to put locale_XX.qm files in it. How to obtain a qm file for your plugin? Run :(replace XX by the targetted language) lupdate translations/locale_XX.ts Use Qt Linguist or an xml editor to put the translation in local_XX.ts. Once done run : lrelease locale_XX.ts You will obtain a qm file. Now run MuseScore in your language and your plugin should be translated! ===================================================== Example "run" scripts ===================================================== 1. Create a "hello world" message box var mb = new QMessageBox(); mb.setWindowTitle("MuseScore: Hello"); mb.text = "Hello World!"; mb.exec(); if no "menu" is defined in the mscorePlugin structure, the plugin must be registered in the init() function: function init() { // create action var action = new QAction("mops", mscore); // put action into menu var menu = mscore.fileMenu(); var actionList = menu.actions(); menu.insertAction(actionList[5], action); // register plugin mscore.registerPlugin(action); } 2. Create a new Score "Test-Score" var score = new Score(); score.name = "Test-Score"; score.appendPart("Piano"); // create two staff piano part score.appendMeasures(5); // append five empty measures 3. Put note name above each chord var cursor = new Cursor(curScore); cursor.staff = 0; cursor.voice = 0; cursor.rewind(); while (!cursor.eos()) { if (cursor.isChord()) { var text = new Text(curScore); text.text = cursor.chord().topNote().name(); cursor.putStaffText(text); } cursor.next(); } 4. Remove middle note in all three note chords var cursor = new Cursor(curScore); cursor.staff = 0; cursor.voice = 0; cursor.rewind(); while (!cursor.eos()) { if (cursor.isChord()) { var chord = cursor.chord(); if (chord.notes() == 3) { chord.removeNote(1); } } cursor.next(); } ===================================================== Useful functions ===================================================== 1. Apply the given function "func" to all notes in selection on all voices function applyToNotesInSelection(func) { var cursor = new Cursor(curScore); var selectionEnd = new Cursor(curScore); cursor.goToSelectionStart(); selectionEnd.goToSelectionEnd(); var startStaff = cursor.staff; var endStaff = selectionEnd.staff; for (var staff = startStaff; staff < endStaff; ++staff) { cursor.goToSelectionStart(); for (var v = 0; v < 4; v++) { cursor.goToSelectionStart(); // set voice to 0 cursor.voice = v; //voice has to be set after goTo cursor.staff = staff; while (cursor.tick() < selectionEnd.tick()) { if (cursor.isChord()) { var chord = cursor.chord(); var n = chord.notes; for (var i = 0; i < n; i++) { var note = chord.note(i); func(note); } } cursor.next(); } } } }