Access to selection in plugins

• Aug 26, 2009 - 19:48
S4 - Minor

I would be very neat to have access to the selection in plugins to act on a single note, some note or only a staff.


I agree this would be a really good feature to have. I have a number of plug-in ideas, but all of them would need to be able to act on the selected part of the score.

The plug-in feature would be a convenient way to try out many new features before actually including them in the regular code. I'd like to be able to write plug-ins to do things like combining and splitting measures or changing the duration of several notes at once.

I would like to create a plug in to swap selected voice between stalves over a SELECTED region of score. Using the selected region with the mouse would be handy as to not limit the functionality to whole stalves .. or perhaps measures specified by script gui ui.

another useful plugin would be a basic tool for composers using serial techniques
how a serial music plugin might operate:
- construct a row of 'n' length (12 is usually the length) in one measure on a stave
- select the row
- open the serial music plugin
- press the 'generate' button
- result: a matrix is formed and labeled on staves below the original series/row
- Original, Inversion, Retrograde and Retrograde Inversion

see the following online calculator for more of an idea as to how it could work:

Hi I´m new to plugin development so be gently hehe
I'm using nightly r.2860 Witch is where rewind(1) and rewind(2) are implemented. but...
What should I get from them? or how could I implement it.
I tried on the plugin console (with a part of a score selected)
var cursor = new Cursor (curScore);

and get UNDEFINED as a result.
Tried to do the same on a script with a mb. and It show nothing at all.

Sorry. I tried using
cursor.tick() after that and did get a result.
but for rewind(2) I always get 0 ¿?
and If only one note is selected using rewind(1) I get the last value of rewind (1) on a large selection.

Status (old) fixed active

The typical use case for a selection is to go through all notes selected to do something. I might miss something but how a plugin developer can do this with rewind(1) and rewind(2) ?

Maybe we could have two new methods ?
- bool eoselection() to know if we are at the end of selection, similar to eos()
- rewindSelection() to position the cursor at start of selection, similar to rewind.

Or a global cursor for selection? like curScore but curSelection ?

As a general remark, I'm not sure it's a good idea to use numeric code for different behavior. The API should be simple self explanatory when possible.

In essence the current code does what Miwarre proposed. You can create a cursor to start of selection and a cursor to the end. The current implementation extends the existing cursor functionality and does not create more global names which i like better. It also works with different scores.
Using numbers as parameters is indeed ugly and should be changed. I thought there would be a way to name the numbers later (something like "enums" in C) but there isn't such a mechanism in JaveScript. My proposal is to use strings as parameters to modify the rewind() behaviour.

I'm not really a javascript developer but for me it's more convenient to have a dedicated function in the API instead of rewind with several parameters. From my (small) experience as a javascript programmer for web, it looks more natural.

Sorry to insist... but how can I test I'm at end of selection? Comparing the time or the tick ? It looks cumbersome while it's easy with eos() to check end of score.

I would like the eoSelection() too. But yes you can achieve the same thing with ticks. That is what I have done until now. But only to do something between rewind () and rewind (1). rewind (2) haven't work for me on any nightly so far.
see my previous comments #7 - #8 and //

werner it works great . sorry I must have been doing something wrong... I'm new to javascript and plugins developement.

Thanks for the example Werner. Much appreciated.
I understand now that eoSelection() is not enough. Having a cursor for end of selection gives the ability to know the last staff selected too.

I tried the example on the third measure of Promenade, and it does not work with voices, rewind(1) always sends back to the first voice. If I set the cursor.voice just after rewind(1), MuseScore crashes.

The voice has to be set after rewind(1). The crash is fixed in r2883. To make the example work as expected i also changed the return value for cursor.tick() to return the score tick len if the cursor is at end of score.

Thanks again!
Regarding the use of numbers vs constants, one way could be to use static constant like "Qt::" ones. The file "qtscript_Qt.cpp" in scripgen can be used as an example. I will take a look tomorrow.

Even when toggling the line, the plugin in #14 does not work for measure 3 in Promenade. Voice 2 notes are not colored.

Attached the plugin I'm using to test and a file to test. I find two bugs.

  1. select first measure
  2. Plugin -> Color notes 2
    1. Actual result: the whole score is colored
      Expected result : only the selection should be colored
      1. select 3rd measure. This measure has been written by copy paste of the first measure and Del on the 3 quarters
      2. Plugin -> Color notes 2
        1. Actual result: Only voice 1 notes are colored
          Expected result : All voices should be colored

          Discussion: Using Del on rests is convenient but it's impossible to insert rests once deleted. Invisible rests are more user friendly. See also :

Attachment Size
colornotes2.txt 3.44 KB
testColornotes.mscz 1.55 KB

add(chord) also does not work for voice 2.
try open the code createscore.js
cursor.voice = 0; to 1 or any other


try the plugin in museScore. It does create a score but not the 4 default notes c d e f.

Regarding #11, I have some code to export an enum to the plugin framework from QIODevice. See attached patch. I guess it can be useful for something else.

It works and replace:
rewind(0) --> rewind(Cursor.scoreStart);
rewind(1) --> rewind(Cursor.selectionStart);
rewind(2) --> rewind(Cursor.selectionEnd);

But I'm not happy with it, it's long and not natural. What about 3 functions?

Attachment Size
sccursor.patch 6.57 KB

lasconic does #23 implies that color notes 2 now also works for voice 2 on r2887? ´cause it doesn't do it on my pc.
Windows xp.

I concur with #24 that the rewind() function is not the best choice for replacing the cursor in the score. I would use rewind() for going to the start of the score and use something else like goTo or another naming to replace the cursor. Could we find similar function names in other (Javascript) references?

In r2890, cursor has no more rewind(param) function but
rewind() to go to start of the score

README.scripts contains, at the end, an example of a function to act on each note of a selection by passing another function.

Attached an example with coloring each note according to pitch.

I put the bug report on fixed. Please reopen if you tested with a nightly > 2890 and encounter a critical problem with selection. If not open another bug report.

Attachment Size
colornotes2.txt 3.8 KB

Sorry, but i still don't like this solution. Granted the name "rewind" is wrong for this kind of functionality the exported enum does not buy anything. My suggestion is to name the function "move" and add string parameter:

move("begin selection")
move("end selection")

Instead of a one dimensional list of special functions i want to use function parameters as an additional dimension to structure the exposed functionality.

Before implementing arbitrary functionality in the script interface we should try to specify the whole interface to get it consistent and as small as possible. I see the current interface only as experimental to gather some experience as i am not a java script programmer and the qt interface is complex and hard to understand (at least for me). But the current implementation looks promising so we can start this next step.
Problem is that the more plugins are there the more difficult it will be to change the interface. The interface therefore must be an abstraction of the MuseScore internal structures (which will change). This also means that not all internal details can be exposed.

And all this should be discussed elsewhere and not in the issue tracker...

Interesting discussion. I see two different approaches here. While lasconic had the intention to find out the best function names which read well, Werner goes for the least amount of functions using parameters in order to experiment. Two different strategies but both with the same intention: making it third party developers as easy as possible to develop plugins.

I'm not a seasoned API developer, so I don't have a personal opinion, but my guess would be to look around and see what approach other open source software have followed. I follow Drupal since many years now and their setup has similarities to MuseScore: one core and modules/extension/plugins around it.

The Drupal development follows the approach of not being backwards compatible. This means that module developers have to upgrade their code once a new Drupal version is released and offer an upgrade path for the data which is often stored in the database.

This strategy has worked pretty well for Drupal since it doesn't halt innovation in the core and it puts less pressure on the core development (team & cycle) as well. The trade off is that the module developers are taking up part of the pressure. However, this is again not that bad since while having to upgrade, the module is often refactored and improved using the latest & greatest API functions.

This is an important discussion and sooner of later, an approach will have to be taken and communicated. We could further discuss this on IRC (#musescore on or on the developer mailing list.

lasconic: Colornotes now works with voices prfectly : )
have you tried to add notes with a plugin on any voice but 0?
For example changing the code for the "create score" plugin haven´t worked for me.