Range selection is asymmetric, causes breakage with measure deletion

• Aug 4, 2020 - 04:40
Reported version
3.4
Priority
P1 - High
Type
Functional
Frequency
Few
Severity
S3 - Major
Reproducibility
Always
Status
closed
Regression
No
Workaround
Yes
Project

Steps to reproduce:
1) Create a score with more than one system (or use uploaded score).
2a) Click on the first note of the last measure in the first system.
2b) Shift-click on the last note of that measure (to select the whole measure).
3a) Click on the last note of the last measure in the first system.
3b) Shift-click on the first note of that measure (to select the whole measure).
4) Delete the measure (by key shortcut or using Remove Selected Range in the Tools menu).

Expected result:
The state is the same after performing 2b) and after performing 3b).
After performing 4), the last measure in the first system is removed, without affecting the contents of the remainder of the score.

Actual result:
After 2b), the whole measure is selected, as expected. After 3b), the whole measure is selected, along with a small piece of the next measure.
After 4), the last measure in the first system is removed, but the first note of the next measure is now concurrent with the second note of that measure. Screen Shot 2020-08-03 at 8.06.50 PM.png

A few notes, for what they're worth:
The asymmetry in forward/reverse selection actually occurs at the end of any measure, but the deletion issue only occurs at the end of a system. Also, the asymmetry shows up in the status line as well as on the score (the reverse selection claims to end on beat 1 of the next measure).

Tested on:
OS: macOS 10.15, Arch.: x86_64, MuseScore version (64-bit): 3.4.2.25137, revision: 148e43f
Also tested on 3.x and 4.0 nightlies:
OS: macOS 10.15, Arch.: x86_64, MuseScore version (64-bit): 3.5.0.28425, revision: aabf881
OS: macOS 10.15, Arch.: x86_64, MuseScore version (64-bit): 4.0.0.28503, revision: da7a4fc

Attachment Size
Selection Bug.mscz 9.32 KB

Comments

Priority P1 - High

I can confirm this. The selection in the second case is wrong in that it extends past the end of the measure; you can see the selection box extend to the next system. The selection actually includes the clef in the system header in the next measure, whereas it really should only extend to the last note of the current measure. Specifically, in the good case, endSegment points to the barline at the end end of the current measure; in the bad case, it points to the first note of the next system. This seems to give localTimeDelete() fits. BTW, if you save / reload the score, the apparent corruption is gone, but so is the first note of the measure

In theory that shouldn't actually cause the strange corruption we see here, so it could be worth addressing that symptom - behavior of the localTimeDelete() when endSegment points to the first note of a measure. But, the selection is bad, and possibly leads to other effects, so better address the actual cause - the bad selection. You can reproduce the same by extending the select backwards from the last note via Shift+Left, so the issue must be somewhere deeper within the select management code, not the Shift+click code specifically.

Status PR created fixed

Fixed in branch 3.x, commit a963bc360a

_fix #308568: bad selection and corruption on delete

Resolves: https://musescore.org/en/node/308568

If you make a range selection "in reverse",
by selecting a note then extending it to the left
(whether using Shift+Left or Shift+click),
you get a bad selection where the endSemgent is in the next measure.
And in the case of a measure at the end of a system,
it means the selection includes the header of the next system.
This glitch has been the case since MuseScore 2 at least,
but with the reimplementation of measure delete as time delete,
it actually causes corruption when deleting the select range.
That is because we are getting the wrong measure
for the end of the selection, and attempting to do a partial time delete
(with length of 0) in the next measure.

This change fixes the basic problem with selection, so reverse selection
no longer causes this bad result.
This is done by adjusting the initial range to end with
the first segment after the originally-selected CR
rather than the last.
I also fix the calculation of the range of measures
to not be fooled if the endSegment comes after a header -
this was causing an unnecessary invocation of time delete
to delete the beginning of that next measure.
Finally, I also check to be sure we aren't trying to delete zero time,
since that was where the corruption was coming from._

Fix version
3.5.1