diff --git a/libmscore/paste.cpp b/libmscore/paste.cpp
index e9af8af8203c..48a8dd889525 100644
--- a/libmscore/paste.cpp
+++ b/libmscore/paste.cpp
@@ -562,13 +562,30 @@ void Score::pasteChordRest(ChordRest* cr, const Fraction& t, const Interval& src
{
Fraction tick(t);
// qDebug("pasteChordRest %s at %d, len %d/%d", cr->name(), tick, cr->ticks().numerator(), cr->ticks().denominator() );
- if (cr->isChord())
- transposeChord(toChord(cr), srcTranspose, tick);
Measure* measure = tick2measure(tick);
if (!measure)
return;
+ int twoNoteTremoloFactor = 1;
+ if (cr->isChord()) {
+ transposeChord(toChord(cr), srcTranspose, tick);
+ if (toChord(cr)->tremolo() && toChord(cr)->tremolo()->twoNotes())
+ twoNoteTremoloFactor = 2;
+ else if (cr->durationTypeTicks() == (cr->actualTicks() * 2)) {
+ // this could be the 2nd note of a two-note tremolo
+ // check previous CR on same track, if it has a two-note tremolo, then set twoNoteTremoloFactor to 2
+ Segment* seg = measure->undoGetSegment(SegmentType::ChordRest, tick);
+ ChordRest* crt = seg->nextChordRest(cr->track(), true);
+ if (crt && crt->isChord()) {
+ Chord* chrt = toChord(crt);
+ Tremolo* tr = chrt->tremolo();
+ if (tr && tr->twoNotes())
+ twoNoteTremoloFactor = 2;
+ }
+ }
+ }
+
// we can paste a measure rest as such only at start of measure
// and only if the lengths of the rest and measure match
// otherwise, we need to convert to duration rest(s)
@@ -584,7 +601,7 @@ void Score::pasteChordRest(ChordRest* cr, const Fraction& t, const Interval& src
if (cr->isRepeatMeasure())
partialCopy = toRepeatMeasure(cr)->actualTicks() != measure->ticks();
else if (!isGrace && !cr->tuplet())
- partialCopy = cr->durationTypeTicks() != cr->actualTicks();
+ partialCopy = cr->durationTypeTicks() != (cr->actualTicks() * twoNoteTremoloFactor);
// if note is too long to fit in measure, split it up with a tie across the barline
// exclude tuplets from consideration
diff --git a/mtest/libmscore/copypaste/copypaste_tremolo-ref.mscx b/mtest/libmscore/copypaste/copypaste_tremolo-ref.mscx
new file mode 100644
index 000000000000..47fbde33421e
--- /dev/null
+++ b/mtest/libmscore/copypaste/copypaste_tremolo-ref.mscx
@@ -0,0 +1,247 @@
+
+
+
+
+ 0
+ 480
+
+ 1
+ 1
+ 1
+ 0
+
+
+
+
+
+
+
+
+
+
+ voice-paste1
+
+
+
+ Standard
+
+
+ Violin
+
+ Violin
+ Vln.
+ Violin
+ 55
+ 103
+ 55
+ 88
+
+ 24
+ 55
+ 62
+ 69
+ 76
+
+
+ 100
+ 100
+
+
+ 100
+ 50
+
+
+ 100
+ 100
+
+
+ 120
+ 100
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 10
+
+
+ voice-paste
+
+
+
+
+
+ G
+ G
+
+
+ 4
+ 4
+
+
+ quarter
+
+
+ 1
+ half
+ 3/8
+
+ 72
+ 14
+
+
+ c16
+
+
+
+ 1
+ half
+ 3/8
+
+ 76
+ 18
+
+
+
+
+
+ quarter
+
+
+ quarter
+
+ 62
+ 16
+
+
+
+ quarter
+
+ 64
+ 18
+
+
+
+ quarter
+
+ 65
+ 13
+
+
+
+
+
+
+
+ 1
+ quarter
+
+ 72
+ 14
+
+
+
+ eighth
+
+ 76
+ 18
+
+
+
+ half
+
+
+
+
+ quarter
+
+ 62
+ 16
+
+
+
+ quarter
+
+ 64
+ 18
+
+
+
+
+
+
+
+ 1
+ half
+ 3/8
+
+ 72
+ 14
+
+
+ c16
+
+
+
+ 1
+ half
+ 3/8
+
+ 76
+ 18
+
+
+
+ quarter
+
+
+
+
+ quarter
+
+ 62
+ 16
+
+
+
+ quarter
+
+ 64
+ 18
+
+
+
+ quarter
+
+ 65
+ 13
+
+
+
+
+
+
+
+ measure
+ 4/4
+
+
+ end
+ 1
+
+
+
+
+
+
diff --git a/mtest/libmscore/copypaste/copypaste_tremolo.mscx b/mtest/libmscore/copypaste/copypaste_tremolo.mscx
new file mode 100644
index 000000000000..248d1c1ca9bf
--- /dev/null
+++ b/mtest/libmscore/copypaste/copypaste_tremolo.mscx
@@ -0,0 +1,174 @@
+
+
+
+
+ 0
+ 480
+
+ 1
+ 1
+ 1
+ 0
+
+
+
+
+
+
+
+
+
+
+ voice-paste1
+
+
+
+ Standard
+
+
+ Violin
+
+ Violin
+ Vln.
+ Violin
+ 55
+ 103
+ 55
+ 88
+
+ 24
+ 55
+ 62
+ 69
+ 76
+
+
+ 100
+ 100
+
+
+ 100
+ 50
+
+
+ 100
+ 100
+
+
+ 120
+ 100
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 10
+
+
+ voice-paste
+
+
+
+
+
+ G
+ G
+
+
+ 4
+ 4
+
+
+ quarter
+
+
+ 1
+ half
+ 3/8
+
+ 72
+ 14
+
+
+ c16
+
+
+
+ 1
+ half
+ 3/8
+
+ 76
+ 18
+
+
+
+
+
+ quarter
+
+
+ quarter
+
+ 62
+ 16
+
+
+
+ quarter
+
+ 64
+ 18
+
+
+
+ quarter
+
+ 65
+ 13
+
+
+
+
+
+
+
+ measure
+ 4/4
+
+
+
+
+
+
+ measure
+ 4/4
+
+
+
+
+
+
+ measure
+ 4/4
+
+
+ end
+ 1
+
+
+
+
+
+
diff --git a/mtest/libmscore/copypaste/tst_copypaste.cpp b/mtest/libmscore/copypaste/tst_copypaste.cpp
index d60a3d818890..f80906dbb44b 100644
--- a/mtest/libmscore/copypaste/tst_copypaste.cpp
+++ b/mtest/libmscore/copypaste/tst_copypaste.cpp
@@ -36,6 +36,7 @@ class TestCopyPaste : public QObject, public MTest
void copypastestaff(const char*);
void copypastevoice(const char*, int);
void copypastetuplet(const char*);
+ void copypastetremolo();
private slots:
void initTestCase();
@@ -72,6 +73,8 @@ class TestCopyPaste : public QObject, public MTest
void copyPasteTuplet01() { copypastetuplet("01"); }
void copyPasteTuplet02() { copypastetuplet("02"); }
+
+ void copyPasteTremolo01() { copypastetremolo(); }
};
//---------------------------------------------------------
@@ -409,6 +412,67 @@ void TestCopyPaste::copypastetuplet(const char* idx)
delete score;
}
+//---------------------------------------------------------
+// copypastetremolo
+// copy-paste of tremolo between two notes
+//---------------------------------------------------------
+
+void TestCopyPaste::copypastetremolo()
+ {
+ MasterScore* score = readScore(DIR + QString("copypaste_tremolo.mscx"));
+ Measure* m1 = score->firstMeasure();
+ Measure* m2 = m1->nextMeasure();
+ Measure* m3 = m2->nextMeasure();
+
+ QVERIFY(m1 != 0);
+ QVERIFY(m2 != 0);
+ QVERIFY(m3 != 0);
+
+ // create a range selection on 2nd to 3rd beat (voice 1) of first measure
+ SegmentType segTypeCR = SegmentType::ChordRest;
+ Segment* s = m1->first(segTypeCR)->next1(segTypeCR);
+ score->select(static_cast(s->element(1))->notes().at(0));
+ s = s->next1(segTypeCR);
+ score->select(s->element(1), SelectType::RANGE);
+
+ QVERIFY(score->selection().canCopy());
+ QString mimeType = score->selection().mimeType();
+ QVERIFY(!mimeType.isEmpty());
+ QMimeData* mimeData = new QMimeData;
+ mimeData->setData(mimeType, score->selection().mimeData());
+ QApplication::clipboard()->setMimeData(mimeData);
+
+ //paste to second measure
+ score->select(m2->first()->element(0));
+
+ score->startCmd();
+ score->cmdPaste(mimeData,0);
+ score->endCmd();
+
+ // create a range selection on 2nd to 4th beat (voice 0) of first measure
+ s = m1->first(segTypeCR)->next1(segTypeCR);
+ score->select(static_cast(s->element(0))->notes().at(0));
+ s = s->next1(segTypeCR)->next1(segTypeCR);
+ score->select(s->element(0), SelectType::RANGE);
+
+ QVERIFY(score->selection().canCopy());
+ mimeType = score->selection().mimeType();
+ QVERIFY(!mimeType.isEmpty());
+ mimeData->setData(mimeType, score->selection().mimeData());
+ QApplication::clipboard()->setMimeData(mimeData);
+
+ //paste to third measure
+ score->select(m3->first()->element(0));
+
+ score->startCmd();
+ score->cmdPaste(mimeData,0);
+ score->endCmd();
+
+ QVERIFY(saveCompareScore(score, QString("copypaste_tremolo.mscx"),
+ DIR + QString("copypaste_tremolo-ref.mscx")));
+ delete score;
+ }
+
QTEST_MAIN(TestCopyPaste)
#include "tst_copypaste.moc"