Fix crash when deleting overlapped regions.
authorDavid Robillard <d@drobilla.net>
Fri, 14 Nov 2014 02:32:08 +0000 (21:32 -0500)
committerDavid Robillard <d@drobilla.net>
Fri, 14 Nov 2014 02:32:08 +0000 (21:32 -0500)
Use RegionSelection for MIDI regions as well, since the old dumb stub didn't do
some things correctly.  There's probably no reason to have a separate class for
this at all, and some good ones for putting all regions in the same selection,
so we should probably do that.  For now they are still separate in the
selection but use the same base class.

gtk2_ardour/editor_drag.cc
gtk2_ardour/editor_ops.cc
gtk2_ardour/midi_selection.cc
gtk2_ardour/midi_selection.h
gtk2_ardour/region_view.cc

index aa37467f2c18d4e048c3953d6fbdc9eb51ecffad..1f400310ae87de8e40c4d0f6cf6a6331c2b639e7 100644 (file)
@@ -1967,7 +1967,10 @@ NoteResizeDrag::start_grab (GdkEvent* event, Gdk::Cursor* /*ignored*/)
                MidiRegionSelection::iterator next;
                next = r;
                ++next;
-               (*r)->begin_resizing (at_front);
+               MidiRegionView* mrv = dynamic_cast<MidiRegionView*>(*r);
+               if (mrv) {
+                       mrv->begin_resizing (at_front);
+               }
                r = next;
        }
 }
@@ -1979,7 +1982,10 @@ NoteResizeDrag::motion (GdkEvent* /*event*/, bool /*first_move*/)
        for (MidiRegionSelection::iterator r = ms.begin(); r != ms.end(); ++r) {
                NoteBase* nb = reinterpret_cast<NoteBase*> (_item->get_data ("notebase"));
                assert (nb);
-               (*r)->update_resizing (nb, at_front, _drags->current_pointer_x() - grab_x(), relative);
+               MidiRegionView* mrv = dynamic_cast<MidiRegionView*>(*r);
+               if (mrv) {
+                       mrv->update_resizing (nb, at_front, _drags->current_pointer_x() - grab_x(), relative);
+               }
        }
 }
 
@@ -1990,7 +1996,10 @@ NoteResizeDrag::finished (GdkEvent*, bool /*movement_occurred*/)
        for (MidiRegionSelection::iterator r = ms.begin(); r != ms.end(); ++r) {
                NoteBase* nb = reinterpret_cast<NoteBase*> (_item->get_data ("notebase"));
                assert (nb);
-               (*r)->commit_resizing (nb, at_front, _drags->current_pointer_x() - grab_x(), relative);
+               MidiRegionView* mrv = dynamic_cast<MidiRegionView*>(*r);
+               if (mrv) {
+                       mrv->commit_resizing (nb, at_front, _drags->current_pointer_x() - grab_x(), relative);
+               }
        }
 }
 
@@ -1999,7 +2008,10 @@ NoteResizeDrag::aborted (bool)
 {
        MidiRegionSelection& ms (_editor->get_selection().midi_regions);
        for (MidiRegionSelection::iterator r = ms.begin(); r != ms.end(); ++r) {
-               (*r)->abort_resizing ();
+               MidiRegionView* mrv = dynamic_cast<MidiRegionView*>(*r);
+               if (mrv) {
+                       mrv->abort_resizing ();
+               }
        }
 }
 
index 1f23aa43190f6188db1f380ac32b792bf8609c7d..6dbbb4073f297a0708a50e1ae67bb6420893633c 100644 (file)
@@ -4000,8 +4000,10 @@ void
 Editor::cut_copy_midi (CutCopyOp op)
 {
        for (MidiRegionSelection::iterator i = selection->midi_regions.begin(); i != selection->midi_regions.end(); ++i) {
-               MidiRegionView* mrv = *i;
-               mrv->cut_copy_clear (op);
+               MidiRegionView* mrv = dynamic_cast<MidiRegionView*>(*i);
+               if (mrv) {
+                       mrv->cut_copy_clear (op);
+               }
        }
 }
 
index bf9b88899bd2e894df0bfb65095824cdc6058011..f98f696444ca74b464cd896919fdcf6c9e7f21b4 100644 (file)
 
 */
 
-#include "gtkmm2ext/gui_thread.h"
-#include "midi_region_view.h"
 #include "midi_selection.h"
-#include "region_view.h"
 
 MidiRegionSelection::MidiRegionSelection ()
-{
-       RegionView::RegionViewGoingAway.connect (_death_connection, MISSING_INVALIDATOR, boost::bind (&MidiRegionSelection::remove_it, this, _1), gui_context());
-}
+       : RegionSelection ()
+{}
 
-/** Copy constructor.
- *  @param other MidiRegionSelection to copy.
- */
 MidiRegionSelection::MidiRegionSelection (MidiRegionSelection const & other)
-       : std::list<MidiRegionView*> (other)
-{
-       RegionView::RegionViewGoingAway.connect (_death_connection, MISSING_INVALIDATOR, boost::bind (&MidiRegionSelection::remove_it, this, _1), gui_context());
-}
-
+       : RegionSelection (other)
+{}
 
-void
-MidiRegionSelection::remove_it (RegionView* rv)
+MidiRegionSelection&
+MidiRegionSelection::operator= (const MidiRegionSelection& other)
 {
-       MidiRegionView* mrv = dynamic_cast<MidiRegionView*> (rv);
-       remove (mrv);
+       RegionSelection::operator=(other);
+       return *this;
 }
index f2c2d3fc600f1299ec0a3b359008a3dd94e1744c..2aa04356d710bfd375f6201f7fe18769f224b04d 100644 (file)
 #ifndef __ardour_gtk_midi_selection_h__
 #define __ardour_gtk_midi_selection_h__
 
-#include <list>
-#include "pbd/signals.h"
+#include "region_selection.h"
 
 class MidiRegionView;
 class MidiCutBuffer;
 class RegionView;
 
-class MidiRegionSelection : public std::list<MidiRegionView*>
+class MidiRegionSelection : public RegionSelection
 {
 public:
        MidiRegionSelection ();
-       MidiRegionSelection (MidiRegionSelection const &);
+       MidiRegionSelection (const MidiRegionSelection&);
 
-private:
-       void remove_it (RegionView *);  
-       PBD::ScopedConnection _death_connection;
+       MidiRegionSelection& operator= (const MidiRegionSelection&);
 };
 
 struct MidiNoteSelection   : std::list<MidiCutBuffer*> {};
index d4604b265d5985a3fcb398c96cbc7ebd555be0e0..fcdde48487afa0a0527d23e0af260e6ff490ad10 100644 (file)
@@ -225,7 +225,9 @@ RegionView::~RegionView ()
 bool
 RegionView::canvas_group_event (GdkEvent* event)
 {
-       return trackview.editor().canvas_region_view_event (event, group, this);
+       if (!in_destructor) {
+               return trackview.editor().canvas_region_view_event (event, group, this);
+       }
 }
 
 void