Merge pull request #5653 from njvdberg/issue-295207-corrupted-mscz

fix #295207 : Mscz file corrupted after splitting a measure
This commit is contained in:
Dmitri Ovodok 2020-02-11 12:10:18 +02:00 committed by GitHub
commit c5b08ae5fc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 573 additions and 5 deletions

View file

@ -2895,7 +2895,7 @@ void Score::nextInputPos(ChordRest* cr, bool doSelect)
// If measure is zero, append new MeasureBase.
//---------------------------------------------------------
void Score::insertMeasure(ElementType type, MeasureBase* measure, bool createEmptyMeasures)
void Score::insertMeasure(ElementType type, MeasureBase* measure, bool createEmptyMeasures, bool moveSignaturesClef)
{
Fraction tick;
if (measure) {
@ -2972,7 +2972,7 @@ void Score::insertMeasure(ElementType type, MeasureBase* measure, bool createEmp
//
// remove clef, time and key signatures
//
if (mi) {
if (moveSignaturesClef && mi) {
for (int staffIdx = 0; staffIdx < score->nstaves(); ++staffIdx) {
Measure* pm = mi->prevMeasure();
if (pm) {

View file

@ -1087,7 +1087,7 @@ class Score : public QObject, public ScoreElement {
void cmdSelectSection();
void respace(std::vector<ChordRest*>* elements);
void transposeSemitone(int semitone);
void insertMeasure(ElementType type, MeasureBase*, bool createEmptyMeasures = false);
void insertMeasure(ElementType type, MeasureBase*, bool createEmptyMeasures = false, bool moveSignaturesClef = true);
Audio* audio() const { return _audio; }
void setAudio(Audio* a) { _audio = a; }
PlayMode playMode() const { return _playMode; }

View file

@ -17,7 +17,9 @@
#include "range.h"
#include "tuplet.h"
#include "spanner.h"
#include "tie.h"
#include "undo.h"
#include "utils.h"
namespace Ms {
@ -70,14 +72,27 @@ void Score::splitMeasure(Segment* segment)
sl.push_back(make_tuple(s, s->tick(), s->ticks()));
}
// Make sure ties are the beginning the split measure are restored.
std::vector<Tie*> ties;
for (int track = 0; track < ntracks(); track++) {
Chord* chord = measure->findChord(stick, track);
if (chord)
for (Note* note : chord->notes()) {
Tie* tie = note->tieBack();
if (tie)
ties.push_back(tie->clone());
}
}
MeasureBase* nm = measure->next();
undoRemoveMeasures(measure, measure);
undoInsertTime(measure->tick(), -measure->ticks());
// create empty measures:
insertMeasure(ElementType::MEASURE, nm, true);
insertMeasure(ElementType::MEASURE, nm, true, false);
Measure* m2 = toMeasure(nm ? nm->prev() : lastMeasure());
insertMeasure(ElementType::MEASURE, m2, true);
insertMeasure(ElementType::MEASURE, m2, true, false);
Measure* m1 = toMeasure(m2->prev());
Fraction tick = segment->tick();
@ -91,6 +106,12 @@ void Score::splitMeasure(Segment* segment)
m2->adjustToLen(ticks2.reduced(), false);
range.write(this, m1->tick());
// Restore ties the the beginning of the split measure.
for (auto tie : ties) {
tie->setEndNote(searchTieNote(tie->startNote()));
undoAddElement(tie);
}
for (auto i : sl) {
Spanner* s = std::get<0>(i);
Fraction t = std::get<1>(i);

View file

@ -0,0 +1,283 @@
<?xml version="1.0" encoding="UTF-8"?>
<museScore version="3.01">
<Score>
<LayerTag id="0" tag="default"></LayerTag>
<currentLayer>0</currentLayer>
<Division>480</Division>
<Style>
<Spatium>1.76389</Spatium>
</Style>
<showInvisible>1</showInvisible>
<showUnprintable>1</showUnprintable>
<showFrames>1</showFrames>
<showMargins>0</showMargins>
<metaTag name="arranger"></metaTag>
<metaTag name="composer"></metaTag>
<metaTag name="copyright"></metaTag>
<metaTag name="lyricist"></metaTag>
<metaTag name="movementNumber"></metaTag>
<metaTag name="movementTitle"></metaTag>
<metaTag name="poet"></metaTag>
<metaTag name="source"></metaTag>
<metaTag name="translator"></metaTag>
<metaTag name="workNumber"></metaTag>
<metaTag name="workTitle">Test</metaTag>
<Part>
<Staff id="1">
<StaffType group="pitched">
<name>stdNormal</name>
</StaffType>
</Staff>
<trackName>Voice</trackName>
<Instrument>
<trackName>Voice</trackName>
<minPitchP>36</minPitchP>
<maxPitchP>94</maxPitchP>
<minPitchA>40</minPitchA>
<maxPitchA>79</maxPitchA>
<Articulation>
<velocity>100</velocity>
<gateTime>100</gateTime>
</Articulation>
<Articulation name="staccato">
<velocity>100</velocity>
<gateTime>85</gateTime>
</Articulation>
<Articulation name="tenuto">
<velocity>100</velocity>
<gateTime>100</gateTime>
</Articulation>
<Articulation name="sforzato">
<velocity>120</velocity>
<gateTime>100</gateTime>
</Articulation>
<Channel>
</Channel>
</Instrument>
</Part>
<Staff id="1">
<VBox>
<height>10</height>
<Text>
<style>Title</style>
<text>Test</text>
</Text>
<Text>
<style>Subtitle</style>
<text>Split Measure within Time Signature change</text>
</Text>
</VBox>
<Measure>
<voice>
<Clef>
<concertClefType>G</concertClefType>
<transposingClefType>G</transposingClefType>
</Clef>
<TimeSig>
<sigN>4</sigN>
<sigD>4</sigD>
</TimeSig>
<Chord>
<durationType>quarter</durationType>
<Note>
<pitch>60</pitch>
<tpc>14</tpc>
</Note>
</Chord>
<Chord>
<durationType>quarter</durationType>
<Note>
<pitch>62</pitch>
<tpc>16</tpc>
</Note>
</Chord>
<Spanner type="HairPin">
<HairPin>
<subtype>1</subtype>
</HairPin>
<next>
<location>
<measures>3</measures>
</location>
</next>
</Spanner>
<Chord>
<durationType>quarter</durationType>
<Spanner type="Slur">
<Slur>
</Slur>
<next>
<location>
<measures>1</measures>
<fractions>-1/2</fractions>
</location>
</next>
</Spanner>
<Note>
<pitch>64</pitch>
<tpc>18</tpc>
</Note>
</Chord>
<Chord>
<durationType>quarter</durationType>
<Note>
<Spanner type="Tie">
<Tie>
</Tie>
<next>
<location>
<measures>1</measures>
<fractions>-3/4</fractions>
</location>
</next>
</Spanner>
<pitch>65</pitch>
<tpc>13</tpc>
</Note>
</Chord>
</voice>
</Measure>
<Measure len="1/4">
<voice>
<TimeSig>
<sigN>2</sigN>
<sigD>4</sigD>
</TimeSig>
<Chord>
<durationType>quarter</durationType>
<Spanner type="Slur">
<prev>
<location>
<measures>-1</measures>
<fractions>1/2</fractions>
</location>
</prev>
</Spanner>
<Note>
<Spanner type="Tie">
<prev>
<location>
<measures>-1</measures>
<fractions>3/4</fractions>
</location>
</prev>
</Spanner>
<pitch>65</pitch>
<tpc>13</tpc>
</Note>
</Chord>
</voice>
</Measure>
<Measure len="1/4">
<voice>
<Chord>
<durationType>quarter</durationType>
<Spanner type="Slur">
<Slur>
</Slur>
<next>
<location>
<measures>1</measures>
<fractions>1/4</fractions>
</location>
</next>
</Spanner>
<Note>
<Spanner type="Tie">
<Tie>
</Tie>
<next>
<location>
<measures>1</measures>
</location>
</next>
</Spanner>
<pitch>67</pitch>
<tpc>15</tpc>
</Note>
</Chord>
</voice>
</Measure>
<Measure>
<voice>
<KeySig>
<accidental>2</accidental>
</KeySig>
<TimeSig>
<sigN>4</sigN>
<sigD>4</sigD>
</TimeSig>
<Chord>
<durationType>quarter</durationType>
<Spanner type="Slur">
<Slur>
</Slur>
<next>
<location>
<fractions>1/4</fractions>
</location>
</next>
</Spanner>
<Note>
<Spanner type="Tie">
<prev>
<location>
<measures>-1</measures>
</location>
</prev>
</Spanner>
<pitch>67</pitch>
<tpc>15</tpc>
</Note>
</Chord>
<Chord>
<durationType>quarter</durationType>
<Spanner type="Slur">
<prev>
<location>
<measures>-1</measures>
<fractions>-1/4</fractions>
</location>
</prev>
</Spanner>
<Spanner type="Slur">
<prev>
<location>
<fractions>-1/4</fractions>
</location>
</prev>
</Spanner>
<Note>
<pitch>69</pitch>
<tpc>17</tpc>
</Note>
</Chord>
<Spanner type="HairPin">
<prev>
<location>
<measures>-3</measures>
</location>
</prev>
</Spanner>
<Chord>
<durationType>quarter</durationType>
<Note>
<pitch>71</pitch>
<tpc>19</tpc>
</Note>
</Chord>
<Chord>
<durationType>quarter</durationType>
<Note>
<Accidental>
<subtype>accidentalNatural</subtype>
</Accidental>
<pitch>72</pitch>
<tpc>14</tpc>
</Note>
</Chord>
</voice>
</Measure>
</Staff>
</Score>
</museScore>

View file

@ -0,0 +1,263 @@
<?xml version="1.0" encoding="UTF-8"?>
<museScore version="3.01">
<Score>
<LayerTag id="0" tag="default"></LayerTag>
<currentLayer>0</currentLayer>
<Division>480</Division>
<Style>
<Spatium>1.76389</Spatium>
</Style>
<showInvisible>1</showInvisible>
<showUnprintable>1</showUnprintable>
<showFrames>1</showFrames>
<showMargins>0</showMargins>
<metaTag name="arranger"></metaTag>
<metaTag name="composer"></metaTag>
<metaTag name="copyright"></metaTag>
<metaTag name="lyricist"></metaTag>
<metaTag name="movementNumber"></metaTag>
<metaTag name="movementTitle"></metaTag>
<metaTag name="poet"></metaTag>
<metaTag name="source"></metaTag>
<metaTag name="translator"></metaTag>
<metaTag name="workNumber"></metaTag>
<metaTag name="workTitle">Test</metaTag>
<Part>
<Staff id="1">
<StaffType group="pitched">
<name>stdNormal</name>
</StaffType>
</Staff>
<trackName>Voice</trackName>
<Instrument>
<trackName>Voice</trackName>
<minPitchP>36</minPitchP>
<maxPitchP>94</maxPitchP>
<minPitchA>40</minPitchA>
<maxPitchA>79</maxPitchA>
<Articulation>
<velocity>100</velocity>
<gateTime>100</gateTime>
</Articulation>
<Articulation name="staccato">
<velocity>100</velocity>
<gateTime>85</gateTime>
</Articulation>
<Articulation name="tenuto">
<velocity>100</velocity>
<gateTime>100</gateTime>
</Articulation>
<Articulation name="sforzato">
<velocity>120</velocity>
<gateTime>100</gateTime>
</Articulation>
<Channel>
</Channel>
</Instrument>
</Part>
<Staff id="1">
<VBox>
<height>10</height>
<Text>
<style>Title</style>
<text>Test</text>
</Text>
<Text>
<style>Subtitle</style>
<text>Split Measure within Time Signature change</text>
</Text>
</VBox>
<Measure>
<voice>
<Clef>
<concertClefType>G</concertClefType>
<transposingClefType>G</transposingClefType>
</Clef>
<TimeSig>
<sigN>4</sigN>
<sigD>4</sigD>
</TimeSig>
<Chord>
<durationType>quarter</durationType>
<Note>
<pitch>60</pitch>
<tpc>14</tpc>
</Note>
</Chord>
<Chord>
<durationType>quarter</durationType>
<Note>
<pitch>62</pitch>
<tpc>16</tpc>
</Note>
</Chord>
<Spanner type="HairPin">
<HairPin>
<subtype>1</subtype>
</HairPin>
<next>
<location>
<measures>2</measures>
</location>
</next>
</Spanner>
<Chord>
<durationType>quarter</durationType>
<Spanner type="Slur">
<Slur>
</Slur>
<next>
<location>
<measures>1</measures>
<fractions>-1/2</fractions>
</location>
</next>
</Spanner>
<Note>
<pitch>64</pitch>
<tpc>18</tpc>
</Note>
</Chord>
<Chord>
<durationType>quarter</durationType>
<Note>
<Spanner type="Tie">
<Tie>
</Tie>
<next>
<location>
<measures>1</measures>
<fractions>-3/4</fractions>
</location>
</next>
</Spanner>
<pitch>65</pitch>
<tpc>13</tpc>
</Note>
</Chord>
</voice>
</Measure>
<Measure>
<voice>
<TimeSig>
<sigN>2</sigN>
<sigD>4</sigD>
</TimeSig>
<Chord>
<durationType>quarter</durationType>
<Spanner type="Slur">
<prev>
<location>
<measures>-1</measures>
<fractions>1/2</fractions>
</location>
</prev>
</Spanner>
<Note>
<Spanner type="Tie">
<prev>
<location>
<measures>-1</measures>
<fractions>3/4</fractions>
</location>
</prev>
</Spanner>
<pitch>65</pitch>
<tpc>13</tpc>
</Note>
</Chord>
<Chord>
<durationType>quarter</durationType>
<Spanner type="Slur">
<Slur>
</Slur>
<next>
<location>
<measures>1</measures>
</location>
</next>
</Spanner>
<Note>
<Spanner type="Tie">
<Tie>
</Tie>
<next>
<location>
<measures>1</measures>
<fractions>-1/4</fractions>
</location>
</next>
</Spanner>
<pitch>67</pitch>
<tpc>15</tpc>
</Note>
</Chord>
</voice>
</Measure>
<Measure>
<voice>
<KeySig>
<accidental>2</accidental>
</KeySig>
<TimeSig>
<sigN>4</sigN>
<sigD>4</sigD>
</TimeSig>
<Chord>
<durationType>quarter</durationType>
<Note>
<Spanner type="Tie">
<prev>
<location>
<measures>-1</measures>
<fractions>1/4</fractions>
</location>
</prev>
</Spanner>
<pitch>67</pitch>
<tpc>15</tpc>
</Note>
</Chord>
<Chord>
<durationType>quarter</durationType>
<Spanner type="Slur">
<prev>
<location>
<measures>-1</measures>
</location>
</prev>
</Spanner>
<Note>
<pitch>69</pitch>
<tpc>17</tpc>
</Note>
</Chord>
<Spanner type="HairPin">
<prev>
<location>
<measures>-2</measures>
</location>
</prev>
</Spanner>
<Chord>
<durationType>quarter</durationType>
<Note>
<pitch>71</pitch>
<tpc>19</tpc>
</Note>
</Chord>
<Chord>
<durationType>quarter</durationType>
<Note>
<Accidental>
<subtype>accidentalNatural</subtype>
</Accidental>
<pitch>72</pitch>
<tpc>14</tpc>
</Note>
</Chord>
</voice>
</Measure>
</Staff>
</Score>
</museScore>

View file

@ -58,6 +58,7 @@ class TestSplit : public QObject, public MTest
split("split184061-keep-tie-before-break-voice-4.mscx", "split184061-keep-tie-before-break-voice-4-ref.mscx", 2); // splitting 1/64th after middle of measure...voice 4 already has a tie that need to be preserved after splitting, and voice 2 has whole note that must be split up with triple-dotted
split("split184061-other-inst-only-one-tie.mscx", "split184061-other-inst-only-one-tie-ref.mscx", 2); // only the one tied note of the chord in the flute should still be tied over
}
void split295207() { split("split295207.mscx", "split295207-ref.mscx", 5) ; }
};
//---------------------------------------------------------