Plugin Range Selection Blues (i.e., not working as expected)

• Mar 30, 2021 - 00:30

I have been unable to get a selection range created inside a Plugin to work as expected. Maybe it's a bug, tho more likely I'm missing something. So could use some help.

My Goal: I have a score with two staffs, one standard notation staff and one TAB staff. My Plugin needs to read stuff from the standard staff and write chords and the like to the TAB staff. But before I start writing on the TAB staff I wish to cleanly clear it out. While I can kinda do that by walking the TAB staff and deleting detected elements one-by-one I believe it would be more reliable, not to mention simpler, to select the relevant range, then issue the cmd("delete") command from the Plugin. Note that part of the requirement is that the user be able to select less than the entire standard staff to start the plugin with. I.e., a partial range selection on the standard staff is meant to be a valid input to the plugin.

I have proven that I can manually select any range in a score, then execute a plugin which executes the cmd("delete") statement; and it successfully deletes the user-selected range.

I have also proven that I can create a range selection in the plugin; and if I end the plugin right after it creates the range. the created range will show in the user interface. Further, with the plugin's created range showing in the user interface, if I then tap my keyboard's delete key that range is properly deleted, as expected. Thus implying that the range as created by the plugin is valid and proper.

However, I have been unable to cause a plugin-created range to get deleted inside my plugin. In addition, once I have created the range inside my plugin I cannot even get the cursor.rewind() statements to return anything other the cursor landing on tick 0. The selection object also returns null for the startSegment / endSegment properties. So this must be telling me something; but what?

One more odd, yet hopeful!?, behaviour: If I select the entire standard staff before executing my plugin then the cmd("delete") statement does work - the entire TAB staff gets deleted. Although the cursor.rewind() actions still don't seem to move the cursor. So....I am duly perplexed.

A demo score and plugin file attached:

Start by selecting, say, measures 2-3 on the standard staff, then run the plugin with the console window open to see debug messages.


Possibly this happens because internally range selection gets updated only when endCmd() is invoked. This is done automatically after a plugin terminates its execution (and actually after any other user action too). If your plugin needs to get a range selection updated during its execution you can call endCmd() after setting a range selection (and startCmd() after that if your plugin needs to edit a score later). This is not needed for a non-range selection, and the documentation seems to miss that difference.

In reply to by dmitrio95

OK, adding the startCmd() call does fix the issue.

Now, curious minds would like to know why this is necessary ? If i'm in the Plugin API and I am operating on an object exposed to the Plugin then, to my mind, we shouldn't have to rely on a call back out to the user interface to complete that object's behaviour. Perhaps there is some rationale for this? Or perhaps it is an artifact of the underlying Musescore source code (i.e., the source sort of naturally led to this plugin behavior)?

To my way of thinking the selection object in the Plugin API ought to have a 'delete' method that does not rely on calls back out to the UI.

In any case, you have solved this issue for me. Thanks much dimitrio.

Do you still have an unanswered question? Please log in first to post your question.