From 37a34bb8b0568ad28fa6c3697a2eab296b0af7ae Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 10 May 2010 16:05:24 +0000 Subject: [PATCH] use a static per-class signal to notify the selection object in each MidiRegionView when note items are deleted. fixes crash on cut/undo/reselect and related operations git-svn-id: svn://localhost/ardour2/branches/3.0@7092 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/canvas-note-event.cc | 4 ++- gtk2_ardour/canvas-note-event.h | 2 ++ gtk2_ardour/midi_region_view.cc | 55 +++++++++++++++++++++----------- gtk2_ardour/midi_region_view.h | 3 ++ 4 files changed, 45 insertions(+), 19 deletions(-) diff --git a/gtk2_ardour/canvas-note-event.cc b/gtk2_ardour/canvas-note-event.cc index 7fdb931ba9..0ad6cd2be9 100644 --- a/gtk2_ardour/canvas-note-event.cc +++ b/gtk2_ardour/canvas-note-event.cc @@ -30,6 +30,8 @@ using ARDOUR::MidiModel; namespace Gnome { namespace Canvas { +PBD::Signal1 CanvasNoteEvent::CanvasNoteEventDeleted; + /// dividing the hue circle in 16 parts, hand adjusted for equal look, courtesy Thorsten Wilms const uint32_t CanvasNoteEvent::midi_channel_colors[16] = { 0xd32d2dff, 0xd36b2dff, 0xd3972dff, 0xd3d12dff, @@ -53,7 +55,7 @@ CanvasNoteEvent::CanvasNoteEvent(MidiRegionView& region, Item* item, CanvasNoteEvent::~CanvasNoteEvent() { - cerr << "Destroying CNE @ " << this << endl; + CanvasNoteEventDeleted (this); if (_text) { _text->hide(); diff --git a/gtk2_ardour/canvas-note-event.h b/gtk2_ardour/canvas-note-event.h index 9546141d8b..af5dd24102 100644 --- a/gtk2_ardour/canvas-note-event.h +++ b/gtk2_ardour/canvas-note-event.h @@ -62,6 +62,8 @@ public: virtual ~CanvasNoteEvent(); + static PBD::Signal1 CanvasNoteEventDeleted; + virtual void show() = 0; virtual void hide() = 0; virtual bool on_event(GdkEvent* ev); diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc index 26490f76e7..f33c15079d 100644 --- a/gtk2_ardour/midi_region_view.cc +++ b/gtk2_ardour/midi_region_view.cc @@ -178,6 +178,10 @@ MidiRegionView::MidiRegionView (const MidiRegionView& other, boost::shared_ptrmidi_source(0)->load_model(); } @@ -789,6 +793,8 @@ MidiRegionView::redisplay_model() MidiModel::Notes& notes (_model->notes()); _optimization_iterator = _events.begin(); + cerr << "++++++++++ MIDI REdisplay\n"; + for (MidiModel::Notes::iterator n = notes.begin(); n != notes.end(); ++n) { boost::shared_ptr note (*n); @@ -830,6 +836,7 @@ MidiRegionView::redisplay_model() } } + /* remove note items that are no longer valid */ for (Events::iterator i = _events.begin(); i != _events.end(); ) { @@ -948,6 +955,8 @@ MidiRegionView::~MidiRegionView () { in_destructor = true; + note_delete_connection.disconnect (); + delete _list_editor; RegionViewGoingAway (this); /* EMIT_SIGNAL */ @@ -1472,6 +1481,18 @@ MidiRegionView::next_program(CanvasProgramChange& program) } } +void +MidiRegionView::maybe_remove_deleted_note_from_selection (CanvasNoteEvent* cne) +{ + if (_selection.empty()) { + return; + } + + if (_selection.erase (cne) > 0) { + cerr << "Erased a CNE from selection\n"; + } +} + void MidiRegionView::delete_selection() { @@ -1756,7 +1777,6 @@ MidiRegionView::add_to_selection (CanvasNoteEvent* ev) } if (_selection.insert (ev).second) { - cerr << "Added CNE to selection, size now " << _selection.size() << endl; ev->selected (true); play_midi_note ((ev)->note()); } @@ -2453,21 +2473,23 @@ MidiRegionView::cut_copy_clear (Editing::CutCopyOp op) break; } - start_delta_command(); + if (op != Copy) { - for (Selection::iterator i = _selection.begin(); i != _selection.end(); ++i) { - switch (op) { - case Copy: - break; - case Cut: - delta_remove_note (*i); - break; - case Clear: - break; - } - } - - apply_delta(); + start_delta_command(); + + for (Selection::iterator i = _selection.begin(); i != _selection.end(); ++i) { + switch (op) { + case Copy: + break; + case Cut: + case Clear: + delta_remove_note (*i); + break; + } + } + + apply_delta(); + } } MidiCutBuffer* @@ -2475,11 +2497,8 @@ MidiRegionView::selection_as_cut_buffer () const { Notes notes; - cerr << "Convert selection of " << _selection.size() << " into a cut buffer\n"; - for (Selection::iterator i = _selection.begin(); i != _selection.end(); ++i) { NoteType* n = (*i)->note().get(); - cerr << "CNE's note is " << n << endl; notes.insert (boost::shared_ptr (new NoteType (*n))); } diff --git a/gtk2_ardour/midi_region_view.h b/gtk2_ardour/midi_region_view.h index d6dd213e72..ea05953080 100644 --- a/gtk2_ardour/midi_region_view.h +++ b/gtk2_ardour/midi_region_view.h @@ -403,6 +403,9 @@ class MidiRegionView : public RegionView MidiListEditor* _list_editor; bool no_sound_notes; + + PBD::ScopedConnection note_delete_connection; + void maybe_remove_deleted_note_from_selection (ArdourCanvas::CanvasNoteEvent*); }; -- 2.30.2