Skip to content

Commit

Permalink
Merge pull request #6099 from blackears/305694-drag-drop-in-PRE-keep-…
Browse files Browse the repository at this point in the history
…NoteEvent

Now keeping length, ontime and velocity data when copying notes.
  • Loading branch information
anatoly-os committed Jun 24, 2020
2 parents 1168e0f + da82d31 commit 670af1f
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 11 deletions.
92 changes: 82 additions & 10 deletions mscore/pianoroll/pianoview.cpp
Expand Up @@ -30,6 +30,7 @@
#include "libmscore/tuplet.h"
#include "libmscore/segment.h"
#include "libmscore/noteevent.h"
#include "libmscore/undo.h"
#include "libmscore/utils.h"

namespace Ms {
Expand Down Expand Up @@ -890,16 +891,36 @@ void PianoView::dragSelectionNoteGroup() {
}


//---------------------------------------------------------
// getSegmentNotes
//---------------------------------------------------------

QVector<Note*> PianoView::getSegmentNotes(Segment* seg, int track)
{
QVector<Note*> notes;

ChordRest* cr = seg->cr(track);
if (cr && cr->isChord()) {
Chord* chord = toChord(cr);
notes.append(QVector<Note*>::fromStdVector(chord->notes()));
}

return notes;
}


//---------------------------------------------------------
// addNote
//---------------------------------------------------------

void PianoView::addNote(Fraction startTick, Fraction duration, int pitch, int track)
QVector<Note*> PianoView::addNote(Fraction startTick, Fraction duration, int pitch, int track)
{
NoteVal nv(pitch);

Score* score = _staff->score();

QVector<Note*> addedNotes;

ChordRest* curCr = score->findCR(startTick, track);
if (curCr) {
ChordRest* cr0 = nullptr;
Expand All @@ -919,23 +940,34 @@ void PianoView::addNote(Fraction startTick, Fraction duration, int pitch, int tr
cutChordRest(cr1, track, startTick + duration, crMid, crEnd);
if (crMid->isChord()) {
Chord* ch = toChord(crMid);
score->addNote(ch, nv);
addedNotes.append(score->addNote(ch, nv));
}
else {
Segment* newSeg = score->setNoteRest(crMid->segment(), track, nv, duration);
if (newSeg)
addedNotes.append(getSegmentNotes(newSeg, track));
}
else
score->setNoteRest(crMid->segment(), track, nv, duration);
}
else if (cr1End == startTick + duration) {
if (cr1->isChord()) {
Chord* ch = toChord(cr1);
score->addNote(ch, nv);
addedNotes.append(score->addNote(ch, nv));
}
else {
Segment* newSeg = score->setNoteRest(cr1->segment(), track, nv, duration);
if (newSeg)
addedNotes.append(getSegmentNotes(newSeg, track));
}
else
score->setNoteRest(cr1->segment(), track, nv, duration);
}
else
score->setNoteRest(cr1->segment(), track, nv, duration);
else {
Segment* newSeg = score->setNoteRest(cr1->segment(), track, nv, duration);
if (newSeg)
addedNotes.append(getSegmentNotes(newSeg, track));
}

}

return addedNotes;
}


Expand Down Expand Up @@ -1845,13 +1877,29 @@ QString PianoView::serializeSelectedNotes()

int voice = note->voice();

int veloOff = note->veloOffset();
Note::ValueType veloType = note->veloType();

xml.writeStartElement("note");
xml.writeAttribute("startN", QString::number(startTick.numerator()));
xml.writeAttribute("startD", QString::number(startTick.denominator()));
xml.writeAttribute("lenN", QString::number(len.numerator()));
xml.writeAttribute("lenD", QString::number(len.denominator()));
xml.writeAttribute("pitch", QString::number(pitch));
xml.writeAttribute("voice", QString::number(voice));
xml.writeAttribute("veloOff", QString::number(veloOff));
xml.writeAttribute("veloType", veloType == Note::ValueType::OFFSET_VAL ? "o" : "u");

for (NoteEvent& evt : note->playEvents()) {
int ontime = evt.ontime();
int len = evt.len();

xml.writeStartElement("evt");
xml.writeAttribute("ontime", QString::number(ontime));
xml.writeAttribute("len", QString::number(len));
xml.writeEndElement();
}

xml.writeEndElement();
}
}
Expand Down Expand Up @@ -1978,6 +2026,7 @@ void PianoView::pasteNotes(const QString& copiedNotes, Fraction pasteStartTick,

QXmlStreamReader xml(copiedNotes);
Fraction firstTick;
QVector<Note*> addedNotes;

while (!xml.atEnd()) {
QXmlStreamReader::TokenType tt = xml.readNext();
Expand All @@ -1999,11 +2048,34 @@ void PianoView::pasteNotes(const QString& copiedNotes, Fraction pasteStartTick,
int pitch = xml.attributes().value("pitch").toString().toInt();
int voice = xml.attributes().value("voice").toString().toInt();

int veloOff = xml.attributes().value("veloOff").toString().toInt();
QString veloTypeStrn = xml.attributes().value("veloType").toString();
Note::ValueType veloType = veloTypeStrn == "o" ? Note::ValueType::OFFSET_VAL : Note::ValueType::USER_VAL;

int track = _staff->idx() * VOICES + voice;

Fraction pos = xIsOffset ? startTick + pasteStartTick : startTick - firstTick + pasteStartTick;

addNote(pos, tickLen, pitch + pitchOffset, track);
addedNotes = addNote(pos, tickLen, pitch + pitchOffset, track);
for (Note* note: addedNotes) {
note->setVeloOffset(veloOff);
note->setVeloType(veloType);
}
}
if (xml.name().toString() == "evt") {
int ontime = xml.attributes().value("ontime").toString().toInt();
int len = xml.attributes().value("len").toString().toInt();

NoteEvent ne;
ne.setOntime(ontime);
ne.setLen(len);
for (Note* note: addedNotes) {
NoteEventList& evtList = note->playEvents();
if (!evtList.isEmpty()) {
NoteEvent* evt = note->noteEvent(evtList.length() - 1);
_staff->score()->undo(new ChangeNoteEvent(note, evt, ne));
}
}
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion mscore/pianoroll/pianoview.h
Expand Up @@ -22,6 +22,7 @@ class Score;
class Staff;
class Chord;
class ChordRest;
class Segment;
class Note;
class NoteEvent;
class PianoView;
Expand Down Expand Up @@ -122,12 +123,13 @@ class PianoView : public QGraphicsView {
virtual void drawBackground(QPainter* painter, const QRectF& rect);

void addChord(Chord* _chord, int voice);
QVector<Note*> getSegmentNotes(Segment* seg, int track);
void updateBoundingSize();
void clearNoteData();
void selectNotes(int startTick, int endTick, int lowPitch, int highPitch, NoteSelectType selType);
void showPopupMenu(const QPoint& pos);
bool cutChordRest(ChordRest* targetCr, int track, Fraction cutTick, ChordRest*& cr0, ChordRest*& cr1);
void addNote(Fraction startTick, Fraction duration, int pitch, int track);
QVector<Note*> addNote(Fraction startTick, Fraction duration, int pitch, int track);
void handleSelectionClick();
void insertNote(int modifiers);
Fraction roundToStartBeat(int tick) const;
Expand Down

0 comments on commit 670af1f

Please sign in to comment.