13
0

fix up major thinko's in ArdourCanvas::Group's handling of deletion (both its own, and child items)

This commit is contained in:
Paul Davis 2014-02-12 15:15:27 -05:00
parent 50edf9b626
commit e247103a7e
2 changed files with 40 additions and 12 deletions

View File

@ -68,6 +68,7 @@ private:
Group (Group const &);
void ensure_lut () const;
void invalidate_lut () const;
void clear_items (bool with_delete);
/* our items, from lowest to highest in the stack */
std::list<Item*> _items;

View File

@ -58,7 +58,7 @@ Group::Group (Group* parent, Duple position)
Group::~Group ()
{
clear (true);
clear_items (true);
}
/** @param area Area to draw in this group's coordinates.
@ -199,7 +199,17 @@ Group::remove (Item* i)
return;
}
begin_change ();
/* we cannot call bounding_box() here because that will iterate over
_items, one of which (the argument, i) may be in the middle of
deletion, making it impossible to call compute_bounding_box()
on it.
*/
if (_bounding_box) {
_pre_change_bounding_box = _bounding_box;
} else {
_pre_change_bounding_box = Rect();
}
i->unparent ();
_items.remove (i);
@ -214,16 +224,7 @@ Group::clear (bool with_delete)
{
begin_change ();
for (list<Item*>::iterator i = _items.begin(); i != _items.end(); ++i) {
(*i)->unparent ();
if (with_delete) {
delete *i;
}
}
_items.clear ();
clear_items (with_delete);
invalidate_lut ();
_bounding_box_dirty = true;
@ -231,6 +232,32 @@ Group::clear (bool with_delete)
end_change ();
}
void
Group::clear_items (bool with_delete)
{
for (list<Item*>::iterator i = _items.begin(); i != _items.end(); ) {
list<Item*>::iterator tmp = i;
Item *item = *i;
++tmp;
/* remove from list before doing anything else, because we
* don't want to find the item in _items during any activity
* driven by unparent-ing or deletion.
*/
_items.erase (i);
item->unparent ();
if (with_delete) {
delete item;
}
i = tmp;
}
}
void
Group::raise_child_to_top (Item* i)
{