1) Fix incorrect track2 assignment to spanners on pasting in some
situations due to not handling the case of track2 == -1.
2) Fix staff index checks in ScoreView code to avoid a crash if
incorrect staff index gets recorded to CmdState.
3) Add an assertion to catch invalid negative staff indices recorded
to CmdState.
Fixup for 99c7b0d746
triggerLayout() and triggerLayoutAll() implementations in Element
have an optimization that allows to avoid triggering layout for
elements not yet added to a score by checking the element's parent.
This optimization is not suitable for spanners since they don't have
a parent even when added to a score. This commit adds a missing
implementation of Spanner::triggerLayoutAll() that takes this into
account.
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.
Blind users find it disorienting for the previous element command to wrap to the end,
or for next element to wrap back to the beginning.
Besides, no other navigation commands work that way.
This commit stops that behavior by simply swapping the calls
to Score::lastElement() and Score::firstElement() in the places where this wrapping occurs.
That is, if previous-element finds no previous element,
we return the first element.
- tick names a position on the time axis
- tick is always a Fraction()
- only Measure() and Segment() (and Tuplet?) have a tick value
- tick() for an generic element return only a sensible value if isMeasure() or isSegment() or isSegment(parent())
- "ticks" names a duration stored in a Fraction()
- the tick value for an Segment is relative to its measure
- rename "duration" to "ticks"
- rename afrac() to tick()
- rename rfrac() to rtick()
- rename some variables, changing "fraction" into "tick"
(example: actualFraction() into actualTicks())
- Lyrics ticks are written as Fraction, on read if xmlreader sees a "/" it reads a fraction
else midi ticks for backwards compatibility
Reading of freed memory occurred in ConnectorInfoReader::operator=
(via a connector() call) when removing the connector info from
connector info list. The previous implementation would also work
incorrectly in case of replacing QList to any vector container.
Error was that we need always call element::layout() method. Otherwise position of elements are (0.0 0.0). And painter doesn't draw elements with this position.
And now layout() is called for both visible and invisible elements, but invisible ones don't participate in autoplacement operations, so there is neither performance impact nor invisible elements autoplacement.
This leads to invisible elements collision if you switch visibility, but it is expected I believe, since we position elements for printing, but invisible elements are for playback.