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
This commit is contained in:
parent
05b99bf8da
commit
37a34bb8b0
|
@ -30,6 +30,8 @@ using ARDOUR::MidiModel;
|
|||
namespace Gnome {
|
||||
namespace Canvas {
|
||||
|
||||
PBD::Signal1<void,CanvasNoteEvent*> 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();
|
||||
|
|
|
@ -62,6 +62,8 @@ public:
|
|||
|
||||
virtual ~CanvasNoteEvent();
|
||||
|
||||
static PBD::Signal1<void,CanvasNoteEvent*> CanvasNoteEventDeleted;
|
||||
|
||||
virtual void show() = 0;
|
||||
virtual void hide() = 0;
|
||||
virtual bool on_event(GdkEvent* ev);
|
||||
|
|
|
@ -178,6 +178,10 @@ MidiRegionView::MidiRegionView (const MidiRegionView& other, boost::shared_ptr<M
|
|||
void
|
||||
MidiRegionView::init (Gdk::Color const & basic_color, bool wfd)
|
||||
{
|
||||
CanvasNoteEvent::CanvasNoteEventDeleted.connect (note_delete_connection, MISSING_INVALIDATOR,
|
||||
ui_bind (&MidiRegionView::maybe_remove_deleted_note_from_selection, this, _1),
|
||||
gui_context());
|
||||
|
||||
if (wfd) {
|
||||
midi_region()->midi_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<NoteType> 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<NoteType> (new NoteType (*n)));
|
||||
}
|
||||
|
||||
|
|
|
@ -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*);
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue