From 7318af0fe9469b47ccf00d943105212a776705ff Mon Sep 17 00:00:00 2001 From: Kevin Zander Date: Fri, 23 Feb 2024 14:57:41 -0600 Subject: [PATCH] Fix invalidated iterator when removing notes in Piano Roll (#7080) * Fix invalidated iterator when removing notes in Piano Roll * fixup - typo * Add MidiClip::removeNote(iterator) function * Use iterator version of remoteNote * Fix parameter name * Change variable name again --- include/MidiClip.h | 3 ++- src/gui/editors/PianoRoll.cpp | 2 +- src/tracks/MidiClip.cpp | 27 +++++++++++++++++++++------ 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/include/MidiClip.h b/include/MidiClip.h index c2287bd00..b3ed0d84a 100644 --- a/include/MidiClip.h +++ b/include/MidiClip.h @@ -63,7 +63,8 @@ public: // note management Note * addNote( const Note & _new_note, const bool _quant_pos = true ); - void removeNote( Note * _note_to_del ); + NoteVector::const_iterator removeNote(NoteVector::const_iterator it); + NoteVector::const_iterator removeNote(Note* note); Note * noteAtStep( int _step ); diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index 8f2d964ff..ff8832325 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -2646,7 +2646,7 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me ) ) { // delete this note - m_midiClip->removeNote( note ); + it = m_midiClip->removeNote(it); Engine::getSong()->setModified(); } else diff --git a/src/tracks/MidiClip.cpp b/src/tracks/MidiClip.cpp index b5e764b17..dfee9a5e6 100644 --- a/src/tracks/MidiClip.cpp +++ b/src/tracks/MidiClip.cpp @@ -208,16 +208,30 @@ Note * MidiClip::addNote( const Note & _new_note, const bool _quant_pos ) -void MidiClip::removeNote( Note * _note_to_del ) +NoteVector::const_iterator MidiClip::removeNote(NoteVector::const_iterator it) +{ + instrumentTrack()->lock(); + delete *it; + auto new_it = m_notes.erase(it); + instrumentTrack()->unlock(); + + checkType(); + updateLength(); + + emit dataChanged(); + return new_it; +} + +NoteVector::const_iterator MidiClip::removeNote(Note* note) { instrumentTrack()->lock(); - m_notes.erase(std::remove_if(m_notes.begin(), m_notes.end(), [&](Note* note) + auto it = std::find(m_notes.begin(), m_notes.end(), note); + if (it != m_notes.end()) { - auto shouldRemove = note == _note_to_del; - if (shouldRemove) { delete note; } - return shouldRemove; - }), m_notes.end()); + delete *it; + it = m_notes.erase(it); + } instrumentTrack()->unlock(); @@ -225,6 +239,7 @@ void MidiClip::removeNote( Note * _note_to_del ) updateLength(); emit dataChanged(); + return it; }