Skip to content

Commit ed27d23

Browse files
author
dylan.nicholson
committed
[MU4] fix #8824 - fix pasting notes
1 parent 5c72065 commit ed27d23

File tree

4 files changed

+47
-35
lines changed

4 files changed

+47
-35
lines changed

src/engraving/libmscore/chordrest.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1433,7 +1433,7 @@ void ChordRest::removeMarkings(bool /* keepTremolo */)
14331433
bool ChordRest::isBefore(const ChordRest* o) const
14341434
{
14351435
if (!o || this == o) {
1436-
return true;
1436+
return false;
14371437
}
14381438
int otick = o->tick().ticks();
14391439
int t = tick().ticks();

src/engraving/libmscore/cmd.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -770,6 +770,10 @@ Segment* Score::setNoteRest(Segment* segment, int track, NoteVal nval, Fraction
770770
bool forceAccidental, const std::set<SymId>& articulationIds, bool rhythmic, InputState* externalInputState)
771771
{
772772
Q_ASSERT(segment->segmentType() == SegmentType::ChordRest);
773+
if (segment->measure()->isMMRest()) {
774+
Measure* m = segment->measure()->mmRestFirst();
775+
segment = m->findSegment(SegmentType::ChordRest, m->tick());
776+
}
773777
InputState& is = externalInputState ? (*externalInputState) : _is;
774778

775779
bool isRest = nval.pitch == -1;
@@ -1049,6 +1053,13 @@ Fraction Score::makeGap(Segment* segment, int track, const Fraction& _sd, Tuplet
10491053
tuplet = 0;
10501054
} else {
10511055
if (seg != firstSegment || !keepChord) {
1056+
if (cr->isChord()) {
1057+
for (auto note : toChord(cr)->notes()) {
1058+
_selection.remove(note);
1059+
}
1060+
} else {
1061+
_selection.remove(cr);
1062+
}
10521063
undoRemoveElement(cr);
10531064
}
10541065
// even if there was a tuplet, we didn't remove it
@@ -3773,7 +3784,7 @@ void Score::cmdPitchUp()
37733784
if (el && el->isLyrics()) {
37743785
cmdMoveLyrics(toLyrics(el), Direction::UP);
37753786
} else if (el && (el->isArticulation() || el->isTextBase())) {
3776-
el->undoChangeProperty(Pid::OFFSET, el->offset() + PointF(0.0, -MScore::nudgeStep* el->spatium()), PropertyFlags::UNSTYLED);
3787+
el->undoChangeProperty(Pid::OFFSET, el->offset() + PointF(0.0, -MScore::nudgeStep * el->spatium()), PropertyFlags::UNSTYLED);
37773788
} else if (el && el->isRest()) {
37783789
cmdMoveRest(toRest(el), Direction::UP);
37793790
} else {
@@ -3791,7 +3802,7 @@ void Score::cmdPitchDown()
37913802
if (el && el->isLyrics()) {
37923803
cmdMoveLyrics(toLyrics(el), Direction::DOWN);
37933804
} else if (el && (el->isArticulation() || el->isTextBase())) {
3794-
el->undoChangeProperty(Pid::OFFSET, QVariant::fromValue(el->offset() + PointF(0.0, MScore::nudgeStep* el->spatium())),
3805+
el->undoChangeProperty(Pid::OFFSET, QVariant::fromValue(el->offset() + PointF(0.0, MScore::nudgeStep * el->spatium())),
37953806
PropertyFlags::UNSTYLED);
37963807
} else if (el && el->isRest()) {
37973808
cmdMoveRest(toRest(el), Direction::DOWN);
@@ -3828,7 +3839,7 @@ void Score::cmdPitchUpOctave()
38283839
Element* el = selection().element();
38293840
if (el && (el->isArticulation() || el->isTextBase())) {
38303841
el->undoChangeProperty(Pid::OFFSET,
3831-
QVariant::fromValue(el->offset() + PointF(0.0, -MScore::nudgeStep10* el->spatium())),
3842+
QVariant::fromValue(el->offset() + PointF(0.0, -MScore::nudgeStep10 * el->spatium())),
38323843
PropertyFlags::UNSTYLED);
38333844
} else {
38343845
upDown(true, UpDownMode::OCTAVE);
@@ -3843,7 +3854,7 @@ void Score::cmdPitchDownOctave()
38433854
{
38443855
Element* el = selection().element();
38453856
if (el && (el->isArticulation() || el->isTextBase())) {
3846-
el->undoChangeProperty(Pid::OFFSET, el->offset() + PointF(0.0, MScore::nudgeStep10* el->spatium()), PropertyFlags::UNSTYLED);
3857+
el->undoChangeProperty(Pid::OFFSET, el->offset() + PointF(0.0, MScore::nudgeStep10 * el->spatium()), PropertyFlags::UNSTYLED);
38473858
} else {
38483859
upDown(false, UpDownMode::OCTAVE);
38493860
}

src/engraving/libmscore/edit.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,7 @@ Rest* Score::setRest(const Fraction& _tick, int track, const Fraction& _l, bool
453453
// compute list of durations which will fit l
454454
//
455455
std::vector<TDuration> dList;
456-
if (tuplet || staff->isLocalTimeSignature(tick)) {
456+
if (tuplet || staff->isLocalTimeSignature(tick) || f == Fraction(0, 1)) {
457457
dList = toDurationList(l, useDots);
458458
std::reverse(dList.begin(), dList.end());
459459
} else {

src/engraving/libmscore/paste.cpp

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,6 +1031,18 @@ void Score::pasteSymbols(XmlReader& e, ChordRest* dst)
10311031
} // inner while readNextstartElement()
10321032
} // pasteSymbolList()
10331033

1034+
static Note* replaceNote(ChordRest* target, Note* with, const Fraction& duration)
1035+
{
1036+
Segment* segment = target->isChord() ? target->score()->setNoteRest(toChord(target)->segment(), target->track(), NoteVal(),
1037+
toChord(
1038+
target)->ticks(), Direction::AUTO, false, { }, false,
1039+
&target->score()->inputState()) : target->segment();
1040+
segment = target->score()->setNoteRest(segment, target->track(),
1041+
with->noteVal(), duration, Direction::AUTO, false, {}, false, &target->score()->inputState());
1042+
delete with;
1043+
return toChord(segment->nextChordRest(target->track()))->upNote();
1044+
}
1045+
10341046
//---------------------------------------------------------
10351047
// cmdPaste
10361048
//---------------------------------------------------------
@@ -1059,48 +1071,37 @@ void Score::cmdPaste(const QMimeData* ms, MuseScoreView* view, Fraction scale)
10591071
} else {
10601072
els.append(_selection.elements());
10611073
}
1062-
1074+
Element* newEl = 0;
10631075
for (Element* target : els) {
1076+
if (!target->selected()) { // might be deselected/removed by a previous operation
1077+
continue;
1078+
}
10641079
el->setTrack(target->track());
1065-
Element* nel = el->clone();
1080+
newEl = el->clone();
10661081
addRefresh(target->abbox()); // layout() ?!
10671082
EditData ddata(view);
1068-
ddata.dropElement = nel;
1083+
ddata.dropElement = newEl;
10691084
if (target->acceptDrop(ddata)) {
10701085
if (el->isNote()) {
1071-
// dropping a note replaces and invalidates the target,
1072-
// so we need to deselect it
1073-
ElementType targetType = target->type();
1074-
deselect(target);
1075-
1076-
// perform the drop
1077-
target->drop(ddata);
1078-
1079-
TDuration durationType(duration);
1080-
if (target->isChordRest()) {
1081-
ChordRest* targetCR = dynamic_cast<ChordRest*>(target);
1082-
score()->changeCRlen(targetCR, durationType);
1083-
} else if (target->isNote()) {
1084-
ChordRest* targetCR = dynamic_cast<Note*>(target)->chord();
1085-
score()->changeCRlen(targetCR, durationType);
1086-
}
1087-
1088-
// if the target is a rest rather than a note,
1089-
// a new note is generated, and nel becomes invalid as well
1090-
// (ChordRest::drop() will select it for us)
1091-
if (targetType == ElementType::NOTE) {
1092-
select(nel);
1086+
// duration information needs to be provided separately in this case
1087+
if (target->isNote() && toNote(target)->chord()->ticks() != duration) {
1088+
newEl = replaceNote(toNote(target)->chord(), toNote(newEl), duration);
1089+
} else if (target->isChordRest()) {
1090+
newEl = replaceNote(toChordRest(target), toNote(newEl), duration);
1091+
} else {
1092+
target->drop(ddata);
10931093
}
10941094
} else {
10951095
target->drop(ddata);
10961096
}
1097-
if (_selection.element()) {
1098-
addRefresh(_selection.element()->abbox());
1099-
}
11001097
} else {
1101-
delete nel;
1098+
delete newEl;
1099+
newEl = 0;
11021100
}
11031101
}
1102+
if (newEl) {
1103+
select(newEl);
1104+
}
11041105
} else if ((_selection.isRange() || _selection.isList()) && ms->hasFormat(mimeStaffListFormat)) {
11051106
ChordRest* cr = 0;
11061107
if (_selection.isRange()) {

0 commit comments

Comments
 (0)