Swap notes in measures feature

• Nov 29, 2012 - 16:30
Reported version
S5 - Suggestion


Let's say I have 2 measures (selected via multi-selection):

Part 1: A | B | C
Part 2: D | E | F

I should be able to swap A and D by selecting the measures individually, and then selecting a menu option or keyboard shortcut to simply swap the notes (chords, rests, articulations, lines attached, etc) from A to D and from D to A. This saves countless hours a week in copy-pasting 3 times (first from A to some measure Z, then from D to A, and Z to D).

This should also work for any 2 measures (e.g. A <--> B, or even across pages).
To be clear this function would be limited to a single measure at a time. If the lengths of the measures are different, this does not have to be allowed. This keeps things simple.

I hope this can be included in time for the next release. It would save me a tone of time.


In my opinion this feature would fit best in a plugin, named SwapMeasures or something like that. I'm going to play around with the new plugin framework. If I'm able to create this plugin I'll let you know.

Can you explain the use case? I'm not quite understanding. You have parts for two different instruments, and you decide later that some passage originally scored for one instrument would be better off played on another, and vice versa?

Since MuseScore doens't provide a way to select discontinugous measures, there really wouldnb't be a way of implementing anything like this that I can see, at least not directly. What is it exactly about simply using a third staff as a scratch staff that causes you to need an alternative? Seems this takes only an extra couple of extra seconds on what seems like not a very common operation?

When you put it like that it sounds stupid =p, but really it serves a couple purposes.

1. Arrangement - as you mentioned. Sometimes we don't want to make a dummy staff we have to later delete. It's not convenient when you have a lot of staves in your orchestra score, for example.

2. Structural Changes. Instead of ABC I can rearrange to ACB without having to messily insert measures, copy paste, and delete whole sections at a time.

I didn't mean to make it sound stupid, just trying to figure out how to prioritize it, given that it would mean inventing a whole new interface for mutli-selecting measures. So if there is some other way of accomplish the task that fits better with the current design of MuseScore, that would be much better. So I'm trying to do - and encourage - a little "outside the box" thinking to come up something that would actually be doable that would solve the problem. And part of that means, really doing a good job of defining the problem.

For example, if it were always two adjacent measures - either horizontally or vertically - it would be possible to design a facility that worked on a range selection that consisted of exactly two measures on a single staff or one measure on two consecutive staves. But it sounds like that would not be sufficient. And I'm still trying to understand how either of those uses case would end up being all that common.

As common as note entry? Certainly not.
Common as in [I want to insert something into the middle of this sentence] something useful on a regular basis? Absolutely.

Finale and Sibelius both have the ability to do this (using plugins).

I will make your job much easier - fortunately I am a developer as well (Java, PHP), unfortunately with no time to contribute - but, I respect your position entirely. I did not mean to sound disparaging of your position.

For this to work, you need selections of equal size (e.g. 2 measures here, 2 measures there).
If that isn't the case, then fail validation with a message box informing the user of the length of each selection.

If validation passes,
then it's just copy-paste to secondary clipboard.

AB|CD to swap

AB --> Clipboard 1
CD --> Clipboard 2
Paste from Clipboard 2 to AB location.
Paste from Clipboard 1 to CD location.

If you don't want to deal with a multi-select interface,
where you have to select measures 1,2,3 and 8,9,10,
just make your plugin into 3 parts (3 user actions):

1. Mark Selection A.
2. Mark Selection B.
3. Swap A and B.

If these have shortcuts available, it's still preferable to a scratch staff.
That also solves the problem if there are selections across multiple pages where something like Ctrl-click to multi-select is just difficult.

The problem isn't the implementation - that's trivial. It's the user interface. Remember, as I said, MuseScore simply does not have any concept of discontiguous range selection. There is no way to select the two measures you want to swap. Select one measure, fine, but the moment you try clicking a second measure, you lose the first selection. There is no way to "mark" two separate measures. Furthermore, plugins cannot, as far as I know, interact with the user sequentially in the way you are assuming - no way for a plugin to stop and waiting for the user to make a new selection and then grab that.

So just figuring out how such a facility could from a user perspective - *that's* probably harder than actually implementing it. Which is, again, why I think it important to understand the real world use case here/ Like, how likely is it that the passages to be exchanged would be more than one measure? What about partial measures? Needing to support passages of arbitrary length could increase the complexity immensely.

Maybe you start by explaining how it works in Finale and Sibelius.

Quite simply, just create a second clipboard that is accessible with an assignable keyboard shortcut.

All problems solved, and has even more applications than this one workflow.

This still doesn't solve the selection problem. Just because you have the contents of a measure saved does not mean you know which measure(s) were originally selected to fill that clipboard. That information would nornally be gone by the time you make the second selection.

Or maybe you mean, you are changing this from a request for an automatic exchange facility to a more manual process that simply replaces the explicit use of a scratch measure with explicit use of this "second clipboard"?

Again, it would be most helpful if you explained how this works in Finale and Sibelius.

In Finales and Sibelius this works by the user selection of a single set of measures across 2 staves. They have multiselect, so I assumed that knowledge was unimportant to you because you don't want to implement multiselect.

A second clipboard would circumvent the multi select requirement and be more flexible, which is my feature request to more easily solve this use case.

Please for the love of all that is good in the world do not ask about multiselect again :-). Unless you really want to build it.

I don't wish to implement it indeed. But I don't see why you need to be sarcastic. Were trying to resolve a technical issue, that is all. So I would still like to know more about how it works in Finale and Sibelius.

I think CompleteMusician has actually abandoned the need to have discontinuous range selection. What he needs is the ability to copy to and from 2 separate clipboard storages, preferably with these operations assignable to keyboard shortcuts. Then he can do his 'swap' process with the workflow:

1. Select A
2. Copy to Clipboard 1
3. Select B
4. Copy to Clipboard 2
5. Paste from Clipboard 1
6. Select A again
7. Paste from Clipboard 2

The operations 'cut to clipboard 2', 'copy to clipboard 2' and 'paste from clipboard 2' would need to be available in the shortcuts assignments.

Another option is to restrict this 'swap' process to being available only when the (single) selection range consists of exactly two measures (of the same length), either in the same staff or in adjacent staffs.

A third option I have just thought of would be the ability to swap the current selection with the current clipboard contents. This would make the workflow for an in-music swap:

1. Select A
2. Copy to Clipboard
3. Select B
4. Swap with Clipboard
5. Select A again
6. Paste from Clipboard

I too would benefit from a feature like this.

A possible implementation could be:
1. User selects one or more (whole) source measures in one staff.
2. A menu (either the main menu, or the context menu via a right-click) would have an entry to exchange these selected measures with measures in the same position from another staff. The menu item (perhaps a sub-folder-like item, that itself expands to show other choices) would contain a list of other staves, from which one is chosen as the exchange destination. The menu options could be named something like "Exchange Measures > with part X".

Note that Voice Exchange also appears something like this (under Edit | Voices).

I'm not necessarily interested in selection of partial measures. This could be problematic anyway, e.g. the selected measures across staves did not contain equivalent notes/rhythms etc. So, just an exchange of whole measures would suffice for the vast majority of my needs.

Seems to me that this approach might could be implemented rather easily.

I think Innesw has suggested the most straightforward solution, the "Paste with Swap" (or just "Swap") function. Apparently it is slowly catching on as a useful tool. (see http://peterellisjones.com/post/70523368919/cut-copy-paste-swap )

I envision it working like this...

Select the group of measures A
Select the first measure of B
right click and select a new option, "Swap"
(now the software does what it would usually do with paste, then replaces the clipboard with the items that were deleted in the process .. grab them from the Undo buffer??)
Select the first measure of A

I do like that idea. No major changes needed to underlying architecture of MuseScore, just a single new command that pastes the clipboard to the current position but simulatenously replaces the contents of the clipboard with the original contents of the measures that are being replaced. Chances are pretty good this wouldn't even be terribly hard to implement.

(Posted on IRC)
(jonEnquist) here, working on 19113-swap-notes.
I have an initial solution coded, but have a coding problem, and a stye question.
(coding problem) I would like to extend the current selection to be large enough to accept whatever is in the clipboard.
How could I determine the size (i.e. startStaff, endStaff, startTick, endTick) of the clipboard contents?
(style question) I want to call "normalPaste" but need to know if it was successful. Should I duplicate the code, or move it to a new
funtion bool normalPasteResult(...) and change normalPaste to call the new function?

I don't know an easy way to determine the size of the clipboard. It's basically a XML text representing the selection in more or less the same format as how we would read/write to the file. I guess we could consider adding a field to the clipboard to hold that information - which would be easily known at the point we do the copy into the clipboard - so we don't have to "read" the clipboard to determine its size. Maybe there is another way I am not thinking of, though.

As for getting the result of the paste, I dfinitely vote against any sort of code duplication. If you need the status, why call normalPaste() - why not just call the underlying cmdPaste(), which *does* return status? Or do you mean, you still want to show the dialogs, so that is the code you'd be duplicating? normalPaste() does it's own startCmd()/endCmd(), so I'm not sure it would be a good idea to call it directly from within your code. Hard to say without knowing more about what you are doing.

I discovered the "stafflist" tag at the front of the XML in the clipboard contains attributes "len" and "staves" which supply the information I needed.

I did some experimenting and found the current "undo" "redo" operations do not affect the clipboard contents, so I am not currently concerned about relying on the startcmd() endcmd() in normalPaste(). I also found that while you can select a discontinuous set of notes, do a copy, then select another set of discontinuous notes, or a range, and select "paste," you do not get an error message, but also, nothing seems to happen.

Since the new "swap" operation inherently uses a paste as part of it's function, I'm happiest just calling the existing code at that point. Per the advice of other developers on IRC, I did change "normalPaste" to return the Boolean value I wanted.

I have just achieved my first successful trial of the new code. "It works!"

I expect to send in my pull request by the end of the week.

Ah but "Cut and Copy" "Paste and Swap" has almost a beautiful mathematical symmetry that has been lacking since the paradigm was first invented.

But, I see your point. The fact that they are all grouped together as clipboard operations is
only the merest of clues.

I don't want the menus to get much wider than they are, how about "Paste<->Copy" as the title? Otherwise, I would prefer "Swap Clipboard and Selection," if menu width really isn't a great concern.

Hi Marc, I didn't understand why you think a 2nd clipboard would fail to solve the problem.
If I can cut to clipboard-1 from measures a-to-b, then cut something else to clipboard-2 from measures c-to-d, then paste clipboard-1 to mesure c, then finally paste from clipboard-2 to measure a, wouldn't that solve the problem?

Nevertheless, the swap select vs clipboard sounds like a much better idea to me.

I never said a second clipboard couldn't be useful somehow, just that it would not allow the user to do the specific thing that was being proposed: marking two different selections simultaneously, and then issuing a command to swap them. That quite simply is not possible without first implementing a discontiguous range selection facility - a way to select the two different sections simultaneously.

So the solution actually implemented here is better in my mind because it doesn't require this new discontiguous range selection facility - it's just a single command that works on top of the exisitng selection facility.

In the meantime how about
1. Insert x measures in front of A (or behind)
2. Cut x measures B (this leaves x empty measures behind)
3. Paste B into the newly inserted measures.
4. Cut x measures A.
5. Paste A into empty measures where B was.
Now all you have to do is get rid of the empty measures where A was originally located.
In a one staff score:
6. Delete those measures.
With more than one staff:
6. Cut B
7. Paste B where A was in the beginning.
8. Delete x empty measures.

More steps than above counted, but not that many more.

To summarise "Swap Notes":

1. Select a range of (source) measures and cut/copy.
2. Select a destination measure.
3. Apply paste. The clipboard contents are swapped with the overwritten destination measure(s).
4. Paste again at the source.

Does this work vertically across multiple staves like the current cut/copy/paste commands?

Just to clarify, has the default behavior of paste been changed? Normally the user doesn't want the clipboard modified by pasting. Right? I should be able to use CMD-V several times to post the same thing several times.

This issue reminds me of the old Hewlett Packard calculators (mid seventies?) which had what they called a "stack", a sort of clipboard that could hold four numbers on top of each other that each would be available for calculations (making the use of brackets unnecessary). It took some time to get used to it but it was incredible flexible and fast.

The default behavior of paste has not been changed. Let me amend Geetar's summary :

1. Select a range of (source) measures and cut/copy.
2. Select a destination measure.
3. Apply Swap Clipboard and Selection. The clipboard contents are swapped with the overwritten destination measure(s).
4. Paste again at the source.

And yes, it works across staves, even across different scores, just like regular copy/cut/paste. It's pretty awesome, actually :-) Thanks to Jon and everyone else who contributed to this discussion, which I think produced a great solution.

Hi Marc, can you summarise the use-model of this new feature?
Am I still able to press CMD-V several times to paste the same thing multiple times? Or does every CMD-V swap in the selected region again?

As explained above, there is no change to any existing command. Copy, Cut, and Paste all work exactly the same as always. There a just a brand new command Swap that works as explained above.

See responses 14, 16, 17, and 37. 14 (the "third option" presented) is the original proposal. 16 and 17 confirmed it. 34 attempted to summarize the new feature but contained an error - incorrectly suggesting that the behavior of "paste" was going to be changed to do a swap instead. 37 clarified that paste and swap are two different commands.

Since it is merged, you should be able to easily build this and see for yourself how it works.

But again, to be absolutely perfectly clear: nothing has changed about the existing copy, cut, or paste commands,. They continue to work *exactly* as before. The only thing that has changed is the addition of a single new "swap" command, that works to exchange the contents of the clipboard with the contents of the destination.

Should we have a default keyboard shortcut for the new 'swap' command? If so, is there any consensus in the rest of the computer world about what it would be?

I may have suggested Ctrl-B as it's the next key along the keyboard from CTRL-X/C/V, but we already use CTRL-B for 'Insert Single Measure'. (It would also conflict with CTRL-B while editing text, which is for Bold. BTW, does the swap command actually work while editing text, or just for music?)

//peterellisjones.com/post/70523368919/cut-copy-paste-swap (referred to in comment #16) uses CMD-SHIFT-X (on Macs). Given the relative infrequency of using the command, this is probably as good a choice as any.

I like "Swap with Clipboard," particularly since the current selection will often be extended if the clipboard contents are larger. "Swap Clipboard and (Selection plus more as necessary)" would be quite cumbersome ;)