ExportMidi::writeHeader() would incorrectly write a default C keysig at tick 0 for every iteration through the RepeatList that did not contain a keysig. This meant that if there was an initial keysig, it would have been effectively overwritten it any sections in the RepeatList do not contain any keysig element.
The fix is to only write the fall back default initial C key sig if no key sigs were found at tick 0.
This fixes an bug which produced corrupted measures when splitting irregular length measures. In Score::cmdSplitMeasure() after the newly split measures are first created, if their new actual length was greater than their nominal length, then Measure::adjustToLen() would append additional padding rests at the end of the measure. However, the subsequent range.write() assumed that the measures were entirely empty before copying contents from the original measure into the new measures. The extra padding rests were unnecessary, and caused the resulting measures to contain too many notes than their actual length, hence the corruption.
The fix here is to add a default boolean parameter to adjustToLen() called appendRestsIfNecessary which is true by default so as to not change behavior when it is called without specifiying the parameter. However, cmdSplitMeasure() will call adjustToLen with that boolean explicitly false, so that the new measures don't get unnecessary rests.
Tests for basic functionally. Going between 128th duration & whole duration and applies commands 'half-duration', 'double-duration', 'dec-duration-dotted', 'inc-duration-dotted'
Class Score gets methods cmdDoubleDuration(), cmdHalfDuration(), cmdIncDurationDotted(), cmdDecDurationDotted() which are public wrappers around private method cmdIncDecDurationDotted.
Simplified the text description of the commands
Tries to add long note (breve) after a short 128th rest without crashing. Verifies that the resulting notes are tied over at least 3 times (to span 3 measures) and have total duration the same as a breve.
If an END_START_REPEAT straddles a newline, then:
1. dropping a NORMAL barline on the END_REPEAT will turn the END_REPEAT into NORMAL, but keep the START_REPEAT.
2. dropping a NORMAL barline on the START_REPEAT will remove the START_REPEAT, but keep the END_REPEAT.
Dropping a normal barline onto a pre-existing barline should either turn it into a Normal barline, or if was StartRepeatBarLine, should remove the barline segment.
Any operations dealing with Supplemental Unicode must operate on high & low surrogates simulatenously, since they belong together as a pair:
-Text::insert method has a new version of which takes two QChars as input (the high & low surrogates), and inserts them together before incrementing the cursor.
-TextBlock::fragment method now has return parameter ridx (relative QChar index) in addition to rcol (relative cursor position). For Basic Unicode TextFragments, ridx will be same as rcol, since each Basic Unicode char is one QChar. But for text that has Supplemental Unicode, ridx will be be different since each Supplemental Unicode char is two QChars.
-TextBlock::text method now includes any high surrogate QChars in the returned string. Previously, this method simply skipped over QChars that were high surrogates. When iterating over the TextFragment, only increments col when comming across a QChar that is not a high surrogate.
-Text::createLayout, Text::paste and Text::drop methods now uses the new Text::insert method to insert both high & low surrogates together. Previously, the cursor position would get messed up when each QChar was added seperately.
-TextBlock::remove(int start, int n) will now add both QChars of the surrogate pair to the return string.
Also was issue with adding text after a SMUFL symbol if the cursor mode was already in SMUFL. Fixed by making sure to append a new TextFragment regardless of state of cursor, and also making TextFragment::TextFragment(TextCursor* cursor, const QString& s) constructor set the type to CharFormatType::TEXT.
Previously TextBlock::remove() did not delete Supplementary Multilingual Plane Unicode chars correctly.
Added tests using deletePreviousChar() for SMP Unicode as well as regular BMP Unicode as well as for text that has mixed BMP, SMP, and SMUFL symbols.