fix #288576 : strange results when changing time signature with tremolo between two notes

This commit is contained in:
AntonioBL 2019-10-13 18:45:58 +02:00
parent bbb25ef72e
commit fb55f7e856
6 changed files with 854 additions and 13 deletions

View file

@ -273,7 +273,7 @@ Chord::Chord(const Chord& c, bool link)
}
if (c._tremolo) {
Tremolo* t = new Tremolo(*(c._tremolo));
if (link) {
if (link)
score()->undo(new Link(t, const_cast<Tremolo*>(c._tremolo)));
if (c._tremolo->twoNotes()) {
if (c._tremolo->chord1() == &c)
@ -281,7 +281,6 @@ Chord::Chord(const Chord& c, bool link)
else
t->setChords(nullptr, this);
}
}
add(t);
}
@ -330,9 +329,14 @@ Chord::~Chord()
{
qDeleteAll(_articulations);
delete _arpeggio;
if (_tremolo && _tremolo->chord1() == this) {
if (_tremolo) {
if (_tremolo->chord1() == this) {
Tremolo* tremoloPointer = _tremolo; // setTremolo(0) loses reference to the current pointer
if (_tremolo->chord2())
_tremolo->chord2()->setTremolo(0);
delete tremoloPointer;
}
else if (!(_tremolo->chord1())) // delete orphaned tremolo
delete _tremolo;
}
delete _stemSlash;

View file

@ -25,6 +25,7 @@
#include "staff.h"
#include "excerpt.h"
#include "repeat.h"
#include "tremolo.h"
namespace Ms {
@ -526,6 +527,15 @@ bool TrackList::write(Score* score, const Fraction& tick) const
remains -= gd;
if (cr->isChord()) {
if (!firstpart && toChord(cr)->tremolo() && toChord(cr)->tremolo()->twoNotes()) { // remove partial two-note tremolo
if (toChord(e)->tremolo()->chord1() == toChord(e))
toChord(cr)->tremolo()->setChords(toChord(cr),nullptr);
else
toChord(cr)->tremolo()->setChords(nullptr,toChord(cr));
Tremolo* tremoloPointer = toChord(cr)->tremolo();
toChord(cr)->setTremolo(nullptr);
delete tremoloPointer;
}
for (Note* note : toChord(cr)->notes()) {
if (!duration.isZero() && !note->tieFor()) {
Tie* tie = new Tie(score);

View file

@ -2430,16 +2430,40 @@ void MoveTremolo::redo(EditData*)
oldC1 = trem->chord1();
oldC2 = trem->chord2();
// Move tremolo
// Move tremolo away from old chords
trem->chord1()->setTremolo(nullptr);
trem->chord2()->setTremolo(nullptr);
// Delete old tremolo on c1 and c2, if present
if (c1->tremolo() && (c1->tremolo() != trem)) {
if (c2->tremolo() == c1->tremolo())
c2->tremolo()->setChords(c1,c2);
else
c1->tremolo()->setChords(c1,nullptr);
Tremolo* oldTremolo = c1->tremolo();
c1->setTremolo(nullptr);
delete oldTremolo;
}
if (c2->tremolo() && (c2->tremolo() != trem)) {
c2->tremolo()->setChords(nullptr,c2);
Tremolo* oldTremolo = c2->tremolo();
c2->setTremolo(nullptr);
delete oldTremolo;
}
// Move tremolo to new chords
c1->setTremolo(trem);
c2->setTremolo(trem);
trem->setChords(c1, c2);
trem->setParent(c1);
// Tremolo would cross barline, so remove it
if (m1 != m2)
if (m1 != m2) {
score->undoRemoveElement(trem);
return;
}
// One of the notes crosses a barline, so remove the tremolo
if (c1->ticks() != c2->ticks())
score->undoRemoveElement(trem);
}

View file

@ -0,0 +1,444 @@
<?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>
<pageWidth>8.27</pageWidth>
<pageHeight>11.69</pageHeight>
<pagePrintableWidth>7.4826</pagePrintableWidth>
<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"></metaTag>
<Part>
<Staff id="1">
<StaffType group="pitched">
<name>stdNormal</name>
</StaffType>
</Staff>
<trackName>Piano</trackName>
<Instrument>
<longName>Piano</longName>
<shortName>Pno.</shortName>
<trackName>Piano</trackName>
<minPitchP>21</minPitchP>
<maxPitchP>108</maxPitchP>
<minPitchA>21</minPitchA>
<maxPitchA>108</maxPitchA>
<instrumentId>keyboard.piano</instrumentId>
<Articulation>
<velocity>100</velocity>
<gateTime>95</gateTime>
</Articulation>
<Articulation name="staccatissimo">
<velocity>100</velocity>
<gateTime>33</gateTime>
</Articulation>
<Articulation name="staccato">
<velocity>100</velocity>
<gateTime>50</gateTime>
</Articulation>
<Articulation name="portato">
<velocity>100</velocity>
<gateTime>67</gateTime>
</Articulation>
<Articulation name="tenuto">
<velocity>100</velocity>
<gateTime>100</gateTime>
</Articulation>
<Articulation name="marcato">
<velocity>120</velocity>
<gateTime>67</gateTime>
</Articulation>
<Articulation name="sforzato">
<velocity>150</velocity>
<gateTime>100</gateTime>
</Articulation>
<Articulation name="sforzatoStaccato">
<velocity>150</velocity>
<gateTime>50</gateTime>
</Articulation>
<Articulation name="marcatoStaccato">
<velocity>120</velocity>
<gateTime>50</gateTime>
</Articulation>
<Articulation name="marcatoTenuto">
<velocity>120</velocity>
<gateTime>100</gateTime>
</Articulation>
<Channel>
<program value="0"/>
</Channel>
</Instrument>
</Part>
<Staff id="1">
<Measure>
<voice>
<TimeSig>
<sigN>9</sigN>
<sigD>8</sigD>
</TimeSig>
<Chord>
<durationType>whole</durationType>
<duration>1/2</duration>
<Note>
<pitch>67</pitch>
<tpc>15</tpc>
</Note>
<Tremolo>
<subtype>c32</subtype>
</Tremolo>
</Chord>
<Chord>
<durationType>whole</durationType>
<duration>1/2</duration>
<Note>
<pitch>76</pitch>
<tpc>18</tpc>
</Note>
</Chord>
<Chord>
<durationType>eighth</durationType>
<Note>
<Spanner type="Tie">
<Tie>
</Tie>
<next>
<location>
<measures>1</measures>
<fractions>-1/1</fractions>
</location>
</next>
</Spanner>
<pitch>67</pitch>
<tpc>15</tpc>
</Note>
</Chord>
</voice>
</Measure>
<Measure>
<voice>
<Chord>
<dots>1</dots>
<durationType>quarter</durationType>
<Note>
<Spanner type="Tie">
<prev>
<location>
<measures>-1</measures>
<fractions>1/1</fractions>
</location>
</prev>
</Spanner>
<pitch>67</pitch>
<tpc>15</tpc>
</Note>
</Chord>
<Chord>
<durationType>half</durationType>
<Note>
<pitch>76</pitch>
<tpc>18</tpc>
</Note>
</Chord>
<Chord>
<durationType>quarter</durationType>
<Note>
<Spanner type="Tie">
<Tie>
</Tie>
<next>
<location>
<measures>1</measures>
<fractions>-7/8</fractions>
</location>
</next>
</Spanner>
<pitch>67</pitch>
<tpc>15</tpc>
</Note>
</Chord>
</voice>
</Measure>
<Measure>
<voice>
<Chord>
<durationType>quarter</durationType>
<Note>
<Spanner type="Tie">
<prev>
<location>
<measures>-1</measures>
<fractions>7/8</fractions>
</location>
</prev>
</Spanner>
<pitch>67</pitch>
<tpc>15</tpc>
</Note>
</Chord>
<Chord>
<durationType>half</durationType>
<Note>
<pitch>76</pitch>
<tpc>18</tpc>
</Note>
</Chord>
<Chord>
<dots>1</dots>
<durationType>quarter</durationType>
<Note>
<Spanner type="Tie">
<Tie>
</Tie>
<next>
<location>
<measures>1</measures>
<fractions>-3/4</fractions>
</location>
</next>
</Spanner>
<pitch>67</pitch>
<tpc>15</tpc>
</Note>
</Chord>
</voice>
</Measure>
<Measure>
<voice>
<Chord>
<durationType>eighth</durationType>
<Note>
<Spanner type="Tie">
<prev>
<location>
<measures>-1</measures>
<fractions>3/4</fractions>
</location>
</prev>
</Spanner>
<pitch>67</pitch>
<tpc>15</tpc>
</Note>
</Chord>
<Chord>
<durationType>half</durationType>
<Note>
<pitch>76</pitch>
<tpc>18</tpc>
</Note>
</Chord>
<Chord>
<durationType>half</durationType>
<Note>
<pitch>67</pitch>
<tpc>15</tpc>
</Note>
</Chord>
</voice>
</Measure>
<Measure>
<voice>
<Chord>
<durationType>half</durationType>
<Note>
<pitch>76</pitch>
<tpc>18</tpc>
</Note>
</Chord>
<Chord>
<durationType>half</durationType>
<Note>
<pitch>67</pitch>
<tpc>15</tpc>
</Note>
</Chord>
<Chord>
<durationType>eighth</durationType>
<Note>
<Spanner type="Tie">
<Tie>
</Tie>
<next>
<location>
<measures>1</measures>
<fractions>-1/1</fractions>
</location>
</next>
</Spanner>
<pitch>76</pitch>
<tpc>18</tpc>
</Note>
</Chord>
</voice>
</Measure>
<Measure>
<voice>
<Chord>
<dots>1</dots>
<durationType>quarter</durationType>
<Note>
<Spanner type="Tie">
<prev>
<location>
<measures>-1</measures>
<fractions>1/1</fractions>
</location>
</prev>
</Spanner>
<pitch>76</pitch>
<tpc>18</tpc>
</Note>
</Chord>
<Chord>
<durationType>half</durationType>
<Note>
<pitch>67</pitch>
<tpc>15</tpc>
</Note>
</Chord>
<Chord>
<durationType>quarter</durationType>
<Note>
<Spanner type="Tie">
<Tie>
</Tie>
<next>
<location>
<measures>1</measures>
<fractions>-7/8</fractions>
</location>
</next>
</Spanner>
<pitch>76</pitch>
<tpc>18</tpc>
</Note>
</Chord>
</voice>
</Measure>
<Measure>
<voice>
<Chord>
<durationType>quarter</durationType>
<Note>
<Spanner type="Tie">
<prev>
<location>
<measures>-1</measures>
<fractions>7/8</fractions>
</location>
</prev>
</Spanner>
<pitch>76</pitch>
<tpc>18</tpc>
</Note>
</Chord>
<Chord>
<durationType>half</durationType>
<Note>
<pitch>67</pitch>
<tpc>15</tpc>
</Note>
</Chord>
<Chord>
<dots>1</dots>
<durationType>quarter</durationType>
<Note>
<Spanner type="Tie">
<Tie>
</Tie>
<next>
<location>
<measures>1</measures>
<fractions>-3/4</fractions>
</location>
</next>
</Spanner>
<pitch>76</pitch>
<tpc>18</tpc>
</Note>
</Chord>
</voice>
</Measure>
<Measure>
<voice>
<Chord>
<durationType>eighth</durationType>
<Note>
<Spanner type="Tie">
<prev>
<location>
<measures>-1</measures>
<fractions>3/4</fractions>
</location>
</prev>
</Spanner>
<pitch>76</pitch>
<tpc>18</tpc>
</Note>
</Chord>
<Chord>
<durationType>whole</durationType>
<duration>1/2</duration>
<Note>
<pitch>67</pitch>
<tpc>15</tpc>
</Note>
<Tremolo>
<subtype>c32</subtype>
</Tremolo>
</Chord>
<Chord>
<durationType>whole</durationType>
<duration>1/2</duration>
<Note>
<pitch>76</pitch>
<tpc>18</tpc>
</Note>
</Chord>
</voice>
</Measure>
<Measure>
<voice>
<Chord>
<durationType>whole</durationType>
<duration>1/2</duration>
<Note>
<pitch>67</pitch>
<tpc>15</tpc>
</Note>
<Tremolo>
<subtype>c32</subtype>
</Tremolo>
</Chord>
<Chord>
<durationType>whole</durationType>
<duration>1/2</duration>
<Note>
<pitch>76</pitch>
<tpc>18</tpc>
</Note>
</Chord>
<Rest>
<durationType>eighth</durationType>
</Rest>
</voice>
</Measure>
</Staff>
</Score>
</museScore>

View file

@ -0,0 +1,332 @@
<?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>
<pageWidth>8.27</pageWidth>
<pageHeight>11.69</pageHeight>
<pagePrintableWidth>7.4826</pagePrintableWidth>
<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"></metaTag>
<Part>
<Staff id="1">
<StaffType group="pitched">
<name>stdNormal</name>
</StaffType>
</Staff>
<trackName>Piano</trackName>
<Instrument>
<longName>Piano</longName>
<shortName>Pno.</shortName>
<trackName>Piano</trackName>
<minPitchP>21</minPitchP>
<maxPitchP>108</maxPitchP>
<minPitchA>21</minPitchA>
<maxPitchA>108</maxPitchA>
<instrumentId>keyboard.piano</instrumentId>
<Articulation>
<velocity>100</velocity>
<gateTime>95</gateTime>
</Articulation>
<Articulation name="staccatissimo">
<velocity>100</velocity>
<gateTime>33</gateTime>
</Articulation>
<Articulation name="staccato">
<velocity>100</velocity>
<gateTime>50</gateTime>
</Articulation>
<Articulation name="portato">
<velocity>100</velocity>
<gateTime>67</gateTime>
</Articulation>
<Articulation name="tenuto">
<velocity>100</velocity>
<gateTime>100</gateTime>
</Articulation>
<Articulation name="marcato">
<velocity>120</velocity>
<gateTime>67</gateTime>
</Articulation>
<Articulation name="sforzato">
<velocity>150</velocity>
<gateTime>100</gateTime>
</Articulation>
<Articulation name="sforzatoStaccato">
<velocity>150</velocity>
<gateTime>50</gateTime>
</Articulation>
<Articulation name="marcatoStaccato">
<velocity>120</velocity>
<gateTime>50</gateTime>
</Articulation>
<Articulation name="marcatoTenuto">
<velocity>120</velocity>
<gateTime>100</gateTime>
</Articulation>
<Channel>
<program value="0"/>
</Channel>
</Instrument>
</Part>
<Staff id="1">
<Measure>
<voice>
<TimeSig>
<sigN>4</sigN>
<sigD>4</sigD>
</TimeSig>
<Chord>
<durationType>whole</durationType>
<duration>1/2</duration>
<Note>
<pitch>67</pitch>
<tpc>15</tpc>
</Note>
<Tremolo>
<subtype>c32</subtype>
</Tremolo>
</Chord>
<Chord>
<durationType>whole</durationType>
<duration>1/2</duration>
<Note>
<pitch>76</pitch>
<tpc>18</tpc>
</Note>
</Chord>
</voice>
</Measure>
<Measure>
<voice>
<Chord>
<durationType>whole</durationType>
<duration>1/2</duration>
<Note>
<pitch>67</pitch>
<tpc>15</tpc>
</Note>
<Tremolo>
<subtype>c32</subtype>
</Tremolo>
</Chord>
<Chord>
<durationType>whole</durationType>
<duration>1/2</duration>
<Note>
<pitch>76</pitch>
<tpc>18</tpc>
</Note>
</Chord>
</voice>
</Measure>
<Measure>
<voice>
<Chord>
<durationType>whole</durationType>
<duration>1/2</duration>
<Note>
<pitch>67</pitch>
<tpc>15</tpc>
</Note>
<Tremolo>
<subtype>c32</subtype>
</Tremolo>
</Chord>
<Chord>
<durationType>whole</durationType>
<duration>1/2</duration>
<Note>
<pitch>76</pitch>
<tpc>18</tpc>
</Note>
</Chord>
</voice>
</Measure>
<Measure>
<LayoutBreak>
<subtype>line</subtype>
</LayoutBreak>
<voice>
<Chord>
<durationType>whole</durationType>
<duration>1/2</duration>
<Note>
<pitch>67</pitch>
<tpc>15</tpc>
</Note>
<Tremolo>
<subtype>c32</subtype>
</Tremolo>
</Chord>
<Chord>
<durationType>whole</durationType>
<duration>1/2</duration>
<Note>
<pitch>76</pitch>
<tpc>18</tpc>
</Note>
</Chord>
</voice>
</Measure>
<Measure>
<voice>
<Chord>
<durationType>whole</durationType>
<duration>1/2</duration>
<Note>
<pitch>67</pitch>
<tpc>15</tpc>
</Note>
<Tremolo>
<subtype>c32</subtype>
</Tremolo>
</Chord>
<Chord>
<durationType>whole</durationType>
<duration>1/2</duration>
<Note>
<pitch>76</pitch>
<tpc>18</tpc>
</Note>
</Chord>
</voice>
</Measure>
<Measure>
<voice>
<Chord>
<durationType>whole</durationType>
<duration>1/2</duration>
<Note>
<pitch>67</pitch>
<tpc>15</tpc>
</Note>
<Tremolo>
<subtype>c32</subtype>
</Tremolo>
</Chord>
<Chord>
<durationType>whole</durationType>
<duration>1/2</duration>
<Note>
<pitch>76</pitch>
<tpc>18</tpc>
</Note>
</Chord>
</voice>
</Measure>
<Measure>
<voice>
<Chord>
<durationType>whole</durationType>
<duration>1/2</duration>
<Note>
<pitch>67</pitch>
<tpc>15</tpc>
</Note>
<Tremolo>
<subtype>c32</subtype>
</Tremolo>
</Chord>
<Chord>
<durationType>whole</durationType>
<duration>1/2</duration>
<Note>
<pitch>76</pitch>
<tpc>18</tpc>
</Note>
</Chord>
</voice>
</Measure>
<Measure>
<LayoutBreak>
<subtype>line</subtype>
</LayoutBreak>
<voice>
<Chord>
<durationType>whole</durationType>
<duration>1/2</duration>
<Note>
<pitch>67</pitch>
<tpc>15</tpc>
</Note>
<Tremolo>
<subtype>c32</subtype>
</Tremolo>
</Chord>
<Chord>
<durationType>whole</durationType>
<duration>1/2</duration>
<Note>
<pitch>76</pitch>
<tpc>18</tpc>
</Note>
</Chord>
</voice>
</Measure>
<Measure>
<voice>
<Chord>
<durationType>whole</durationType>
<duration>1/2</duration>
<Note>
<pitch>67</pitch>
<tpc>15</tpc>
</Note>
<Tremolo>
<subtype>c32</subtype>
</Tremolo>
</Chord>
<Chord>
<durationType>whole</durationType>
<duration>1/2</duration>
<Note>
<pitch>76</pitch>
<tpc>18</tpc>
</Note>
</Chord>
</voice>
</Measure>
<Measure>
<voice>
<Chord>
<durationType>whole</durationType>
<duration>1/2</duration>
<Note>
<pitch>67</pitch>
<tpc>15</tpc>
</Note>
<Tremolo>
<subtype>c32</subtype>
</Tremolo>
</Chord>
<Chord>
<durationType>whole</durationType>
<duration>1/2</duration>
<Note>
<pitch>76</pitch>
<tpc>18</tpc>
</Note>
</Chord>
</voice>
</Measure>
</Staff>
</Score>
</museScore>

View file

@ -39,6 +39,7 @@ class TestTimesig : public QObject, public MTest
void timesig06();
void timesig07();
void timesig08();
void timesig09();
void timesig10();
void timesig_78216();
};
@ -230,6 +231,32 @@ void TestTimesig::timesig08()
delete score;
}
//---------------------------------------------------------
// timesig09
// Change timesig with tremolos on notes that end up across barlines
//---------------------------------------------------------
void TestTimesig::timesig09()
{
MasterScore* score = readScore(DIR + "timesig-09.mscx");
QVERIFY(score);
Measure* m = score->firstMeasure();
TimeSig* ts = new TimeSig(score);
ts->setSig(Fraction(9, 8), TimeSigType::NORMAL);
score->startCmd();
score->cmdAddTimeSig(m, 0, ts, false);
score->doLayout();
QVERIFY(saveCompareScore(score, "timesig-09-1.mscx", DIR + "timesig-09-ref.mscx"));
score->endCmd();
// Now undo the change
score->undoStack()->undo(0);
score->doLayout();
QVERIFY(saveCompareScore(score, "timesig-09-2.mscx", DIR + "timesig-09.mscx"));
delete score;
}
//---------------------------------------------------------
// timesig10
// Check if 4/4 is correctly changed to alla breve when commanded to do so