diff --git a/step/worldmodel.cc b/step/worldmodel.cc --- a/step/worldmodel.cc +++ b/step/worldmodel.cc @@ -124,15 +124,15 @@ public: CommandNewItem(WorldModel* worldModel, StepCore::Item* item, StepCore::ItemGroup* parent, bool create) : _worldModel(worldModel), _item(item), _parent(parent), _create(create), _shouldDelete(create) { - if(!create) findLinks(static_cast(_worldModel->world())); + if(!create) findLinks(item, static_cast(_worldModel->world())); } ~CommandNewItem() { if(_shouldDelete) delete _item; } void redo() Q_DECL_OVERRIDE; void undo() Q_DECL_OVERRIDE; protected: - void findLinks(StepCore::ItemGroup* group); + void findLinks(StepCore::Item* itemToMatch, StepCore::ItemGroup* groupToSearch); void removeItem(); void readdItem(); @@ -146,18 +146,31 @@ QList _links; }; -void CommandNewItem::findLinks(StepCore::ItemGroup* group) +void CommandNewItem::findLinks(StepCore::Item* itemToMatch, StepCore::ItemGroup* groupToSearch) { - StepCore::ItemList::const_iterator end = group->items().end(); - for(StepCore::ItemList::const_iterator it = group->items().begin(); it != end; ++it) { - const StepCore::MetaObject* mobj = (*it)->metaObject(); + StepCore::ItemGroup* itemToDeleteGroup = dynamic_cast(_item); + + for (StepCore::Item *item : groupToSearch->items()) { + if (item == itemToMatch) // no need to find links in itself + continue; + if (itemToDeleteGroup && itemToDeleteGroup->contains(item)) // no need to find links if the item is a child of the item that is being deleted + continue; + const StepCore::MetaObject* mobj = item->metaObject(); for(int i=0; ipropertyCount(); ++i) { if(mobj->property(i)->userTypeId() != qMetaTypeId()) continue; - if(_item == mobj->property(i)->readVariant(*it).value()) - _links << qMakePair(static_cast(*it), mobj->property(i)); + if(itemToMatch == mobj->property(i)->readVariant(item).value()) + _links << qMakePair(static_cast(item), mobj->property(i)); } if(mobj->inherits()) - findLinks(static_cast(*it)); + findLinks(itemToMatch, static_cast(item)); + } + + // If the item being deleted is a group, be sure we also find links for all its children + StepCore::ItemGroup* itemToMatchGroup = dynamic_cast(itemToMatch); + if (itemToMatchGroup) { + for (StepCore::Item *child : itemToMatchGroup->items()) { + findLinks(child, groupToSearch); + } } } diff --git a/stepcore/itemgroup.h b/stepcore/itemgroup.h --- a/stepcore/itemgroup.h +++ b/stepcore/itemgroup.h @@ -57,6 +57,8 @@ /** Get list of all direct child items in the ItemGroup */ const ItemList& items() const { return _items; } + bool contains(const Item* item) const { return std::find(_items.begin(), _items.end(), item) != _items.end(); } + /** Get list of all items in the ItemGroup * \note This operation takes long time since it * recursively traverses all child groups */