Resolves: https://musescore.org/en/node/296053
The algorithm for finding a start point for note input works well in most cases,
in particular, if a measure or a note or reset is selected.
The cases were nothing is selected, or an element other than a note or rest is selected,
are sometimes good, sometimes we give up too easily
and select the first (or first visible) measure.
This change improves the no selection case by using the last-selected CR if it is in view
(using the recently-added code for remembering the last selected position).
It improves the case of soemthing other than a note or rest select
by using the actual tick of the element
rather than trying to guess a tick by looking for a parent measure.
That works for elements that are ultimately parented by a measure,
but fails for things like spanners, which are children of the system.
It turns out that SpannerSegment had no tick() function, so this failed at first,
but I added an override, which may well fix some other bug somewhere.
Another side benefit of the change is that if select an element not at the start of the measure
(for examplea mid-measure staff text), input starts at that tick,
not at the beginning of the measure.
In 3.0 - 3.0.5, it was not possible to change the Y position of lyrics.
You could try, and an offset would be recorded, but it would have no effect on layout.
Starting with 3.1, it became possible to change the Y position for lyrics.
For compatibility, we cleared the Y offset when reading 3.0 - 3.0.5 scores,
since it would have been ignored originally.
However, the code doing the version check fails in parts,
because mscoreVersion() returns an empty stirng in that case.
This change simply amends the check to use masterScore() rather than score(),
so parts no longer return an empty version,
and also adds an explicit check for the version being empty,
so the check works correctly in test mode,
where this field is often empty even for the master score.
There turned out to be several aspects to this.
In 3.2.3, we could get a hang if there was literally only one note,
as the navigation would loop back around and we didn't always catch it.
For 3.3 I eliminated the looping back around on navigation,
but neglected to add a check for start/end of score in "fingering mode".
This adds that check (in ScoreView::textTab(), the test for el2 == el).
But further testing revealed further checks we need to make to be safe.
The checks that the current element is actually a child of the note
in Note::nextInEl() and Note::prevInEl() prevents a crash
if one navigates before the fingering has been added to its parent
or after it has been removed (which happens with empty fingering elements).
For consistency with how chord symbols work, and to circumvent other future problems,
I elected to have Space *exit* "fingering mode" after reaching the end of the score.
This required making a reasonable selection (the "exit cleanly" code in textTab)
but also calling mscore->endCmd() and returning immediately in events.cpp in that case.
This had the side benefit of allowing me to remove the updateInspector() call
in textTab(), as it is covered by the endCmd() call.
I should note there are other code paths in, for example, the harmony tab functions,
that can leave an empty / deleted element still selected
when hitting space upon reaching the last note of a score.
But I could cause an actual problem to occur and chose to not deal with that here.
Script test added to cover the basic issue here.
Paste of a note onto a grace note has never worked;
the operation has always been silently rejected.
Now, however, it crashes, because we are attempting to select the note
we think we just pasted.
But there was no reason to reject the operation;
the same code that handles pasting onto a normal note
also works when pasting onto a grace note.
So this change removes the unnecessary check for grace notes.
By removing these four lines of code, it fixes the crash,
and allow the operation to actually succeed where it never did before.
If you move a line into the skyline (e.g, overlapping other elements),
we reduce the min distance automatically and save the result correctly.
But if you reduce the min distance manually via the Inspector
but don't change the offset, then save, the min distance is not written.
That is because we check if the line has been modified before writing these properties.
But we were only checking offset and offset2, not min distance.
This change adds that check.
This was reported original as a crash in fingering entry,
but the underlying problem is in navigation,
When we have run out of notes in the current segment on the current staff,
we should move on to the next segment,
but Segment:nextElementOfSegment() was erroneously finding a note or rest
in voice 4 of the last system.
That is because the loop through the tracks was not handling the end condition properly.
We find an element but don't check that it is on the right staff.
This change simply adds the missing check.
Resolves: https://musescore.org/node/294580.
Right now a courtesy time signature only generates if the local time signature is on the first staff, because the code only checks for the first track. The fix checks for all tracks.
Moved the fix from 7f9f1df8eb to a more
appropriate place so QML palettes can also benefit from it.
Added a test which reproduces this crash without the fix.
The navigation code for next-element and previous-elements ignores measure elements
(elements in the el() list for the measure).
This change adds handling for this
by checking for measure elements before moving to the next or previous measure
in Segment::nextElement() and Segment::previousElement(),
There is corresponding code in Measure::nextElementStaff()
and in Measure::previousElementStaff()
to iterate through multiple elements if present.
Why do these changes fix this particular issue?
After adding any other element, we `setLayout` at the element's
location. However, for boxes, there is an early return, and this step is
missed, meaning the box won't appear until a relevant measure is layed out.
This fix adds the missing `setLayout`.
Provide Note.tieBack & Note.tieForward properties and their
associated Tie objects in QML. Also provides Note.firstTiedNote
and lastTiedNote methods to locate a tie range.
Adds capablity to examine and modify PlayEvent's and a Note's
playEvents list. Adds access to Chord.playEventType. Also
supports UNDO for these operations.
This commit exposes the Score.selection.elements list
enabling QML scripts to manipulate on user selected score elements.
The expectation is that additional selection information will be
provided on this object in the future.