Skip to content

Commit

Permalink
Editor: Deletion in Hierarchy widget can lead to crash #852 (#858)
Browse files Browse the repository at this point in the history
  • Loading branch information
eprikazchikov authored Oct 22, 2024
1 parent 4e53819 commit 16ba4fd
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 42 deletions.
31 changes: 21 additions & 10 deletions worldeditor/src/screens/objecthierarchy/hierarchybrowser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ void HierarchyBrowser::onDrop(QDropEvent *e) {
QString path(e->mimeData()->data(gMimeObject));
foreach(const QString &it, path.split(";")) {
QString id = it.left(it.indexOf(':'));
Object *item = model->findObject(id.toUInt());
Object *item = Engine::findObject(id.toUInt(), model->root());
if(item) {
QModelIndex origin = ui->treeView->indexAt(e->pos());
QModelIndex index = m_filter->mapToSource(origin);
Expand All @@ -309,9 +309,10 @@ void HierarchyBrowser::onDrop(QDropEvent *e) {
index = index.parent();
}

if(item != index.internalPointer()) {
Object *indexObject = Engine::findObject(index.internalId(), model->root());
if(item != indexObject) {
objects.push_back(item);
parent = static_cast<Object *>(index.internalPointer());
parent = indexObject;
}
}
}
Expand All @@ -332,12 +333,14 @@ void HierarchyBrowser::onDrop(QDropEvent *e) {
}

void HierarchyBrowser::onDragStarted(Qt::DropActions supportedActions) {
ObjectHierarchyModel *model = static_cast<ObjectHierarchyModel *>(m_filter->sourceModel());

QMimeData *mimeData = new QMimeData;
QStringList list;
foreach(const QModelIndex &it, ui->treeView->selectionModel()->selectedIndexes()) {
QModelIndex index = m_filter->mapToSource(it);
if(index.column() == 0) {
Object *object = static_cast<Object *>(index.internalPointer());
Object *object = Engine::findObject(index.internalId(), model->root());
list.push_back(QString::number(object->uuid()) + ":" + object->name().c_str());
}
}
Expand All @@ -355,15 +358,17 @@ void HierarchyBrowser::onSelectionChanged(const QItemSelection &selected, const
}

void HierarchyBrowser::on_treeView_clicked(const QModelIndex &index) {
Object *object = static_cast<Object *>(m_filter->mapToSource(index).internalPointer());
ObjectHierarchyModel *model = static_cast<ObjectHierarchyModel *>(m_filter->sourceModel());

Object *object = Engine::findObject(m_filter->mapToSource(index).internalId(), model->root());
Actor *actor = dynamic_cast<Actor *>(object);
if(actor) {
if(index.column() == 0) {
QSet<Object *> set;

QItemSelectionModel *selectionModel = ui->treeView->selectionModel();
for(auto it : selectionModel->selectedIndexes()) {
Object *object = static_cast<Object *>(m_filter->mapToSource(it).internalPointer());
Object *object = Engine::findObject(m_filter->mapToSource(it).internalId(), model->root());

set.insert(object);
}
Expand All @@ -380,7 +385,9 @@ void HierarchyBrowser::on_treeView_clicked(const QModelIndex &index) {
}

void HierarchyBrowser::on_treeView_doubleClicked(const QModelIndex &index) {
Object *object = static_cast<Object *>(m_filter->mapToSource(index).internalPointer());
ObjectHierarchyModel *model = static_cast<ObjectHierarchyModel *>(m_filter->sourceModel());

Object *object = Engine::findObject(m_filter->mapToSource(index).internalId(), model->root());

emit objectsSelected({object}, true);
}
Expand All @@ -390,11 +397,13 @@ void HierarchyBrowser::on_lineEdit_textChanged(const QString &arg1) {
}

void HierarchyBrowser::on_treeView_customContextMenuRequested(const QPoint &pos) {
ObjectHierarchyModel *model = static_cast<ObjectHierarchyModel *>(m_filter->sourceModel());

QItemSelectionModel *select = ui->treeView->selectionModel();

QList<Object *> list;
foreach(QModelIndex it, select->selectedRows()) {
Object *object = static_cast<Object *>(m_filter->mapToSource(it).internalPointer());
Object *object = Engine::findObject(m_filter->mapToSource(it).internalId(), model->root());
Actor *actor = dynamic_cast<Actor *>(object);
if(actor) {
list.push_back(actor);
Expand All @@ -407,7 +416,7 @@ void HierarchyBrowser::on_treeView_customContextMenuRequested(const QPoint &pos)
QPoint point = static_cast<QWidget*>(QObject::sender())->mapToGlobal(pos);

QModelIndex index = ui->treeView->indexAt(pos);
Object *object = static_cast<Object *>(m_filter->mapToSource(index).internalPointer());
Object *object = Engine::findObject(m_filter->mapToSource(index).internalId(), model->root());

if(m_currentEditor) {
QMenu *menu = m_currentEditor->objectMenu(object);
Expand Down Expand Up @@ -442,10 +451,12 @@ bool HierarchyBrowser::eventFilter(QObject *obj, QEvent *event) {
switch(keyEvent->key()) {
case Qt::Key_Delete: {
if(m_currentEditor) {
ObjectHierarchyModel *model = static_cast<ObjectHierarchyModel *>(m_filter->sourceModel());

QList<Object *> list;
QItemSelectionModel *select = ui->treeView->selectionModel();
foreach(QModelIndex it, select->selectedRows()) {
list.push_back(static_cast<Object *>(m_filter->mapToSource(it).internalPointer()));
list.push_back(Engine::findObject(m_filter->mapToSource(it).internalId(), model->root()));
}

m_currentEditor->onObjectsDeleted(list);
Expand Down
37 changes: 9 additions & 28 deletions worldeditor/src/screens/objecthierarchy/objecthierarchymodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,30 +36,11 @@ void ObjectHierarchyModel::showNone() {
m_showNone = true;
}

Object *ObjectHierarchyModel::findObject(const uint32_t uuid, Object *parent) {
Object *result = nullptr;
if(parent == nullptr) {
parent = m_rootItem;
}
for(Object *it : parent->getChildren()) {
if(it->uuid() == uuid) {
return it;
} else {
result = findObject(uuid, it);
if(result != nullptr) {
return result;
}
}
}

return result;
}

QVariant ObjectHierarchyModel::data(const QModelIndex &index, int role) const {
if(!index.isValid()) {
return QVariant();
}
Object *object = static_cast<Object *>(index.internalPointer());
Object *object = Engine::findObject(index.internalId(), m_rootItem);
Actor *actor = dynamic_cast<Actor *>(object);
Scene *scene = dynamic_cast<Scene *>(object);

Expand Down Expand Up @@ -91,7 +72,7 @@ QVariant ObjectHierarchyModel::data(const QModelIndex &index, int role) const {
}
}
} break;
case Qt::BackgroundColorRole: {
case Qt::BackgroundRole: {
if(index.column() == 2 || index.column() == 3) {
return QColor(0, 0, 0, 128);
}
Expand All @@ -104,7 +85,7 @@ QVariant ObjectHierarchyModel::data(const QModelIndex &index, int role) const {
return font;
}
} break;
case Qt::TextColorRole: {
case Qt::ForegroundRole: {
if(actor && actor->isInstance()) {
if(Engine::reference(actor->prefab()).empty()) {
return QColor(255, 95, 82);
Expand All @@ -125,7 +106,7 @@ QVariant ObjectHierarchyModel::data(const QModelIndex &index, int role) const {

bool ObjectHierarchyModel::setData(const QModelIndex &index, const QVariant &value, int role) {
Q_UNUSED(role)
Object *item = static_cast<Object *>(index.internalPointer());
Object *item = Engine::findObject(index.internalId(), m_rootItem);
if(item) {
item->setName(value.toString().toStdString());
}
Expand Down Expand Up @@ -154,7 +135,7 @@ int ObjectHierarchyModel::rowCount(const QModelIndex &parent) const {
if(m_rootItem) {
Object *parentItem = m_rootItem;
if(parent.isValid()) {
parentItem = static_cast<Object *>(parent.internalPointer());
parentItem = Engine::findObject(parent.internalId(), m_rootItem);
}

if(parentItem) {
Expand All @@ -174,7 +155,7 @@ QModelIndex ObjectHierarchyModel::index(int row, int column, const QModelIndex &
Object *ptr = nullptr;
Object *parentItem = m_rootItem;
if(parent.isValid()) {
parentItem = static_cast<Object *>(parent.internalPointer());
parentItem = Engine::findObject(parent.internalId(), m_rootItem);
}

if(parentItem) {
Expand All @@ -193,7 +174,7 @@ QModelIndex ObjectHierarchyModel::index(int row, int column, const QModelIndex &
ptr = *std::next(children.begin(), row-1);
}
}
return createIndex(row, column, ptr);
return createIndex(row, column, ptr->uuid());
}
return QModelIndex();
}
Expand All @@ -203,7 +184,7 @@ QModelIndex ObjectHierarchyModel::parent(const QModelIndex &index) const {
return QModelIndex();
}

Object *childItem = static_cast<Object *>(index.internalPointer());
Object *childItem = Engine::findObject(index.internalId(), m_rootItem);
if(childItem == nullptr) {
return QModelIndex();
}
Expand All @@ -218,7 +199,7 @@ QModelIndex ObjectHierarchyModel::parent(const QModelIndex &index) const {
list.push_back(it);
}
}
return createIndex(list.indexOf(parentItem), 0, parentItem);
return createIndex(list.indexOf(parentItem), 0, parentItem->uuid());
}

Qt::ItemFlags ObjectHierarchyModel::flags(const QModelIndex &index) const {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ class ObjectHierarchyModel : public QAbstractItemModel {

void showNone();

Object *findObject(const uint32_t uuid, Object *parent = nullptr);

private:
QVariant data(const QModelIndex &index, int role) const override;

Expand Down Expand Up @@ -75,7 +73,9 @@ class ObjectsFilter : public QSortFilterProxyModel {
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
bool result = true;

Object *object = static_cast<Object *>(sourceModel()->index(sourceRow, 1, sourceParent).internalPointer());
ObjectHierarchyModel *model = static_cast<ObjectHierarchyModel *>(sourceModel());

Object *object = Engine::findObject(sourceModel()->index(sourceRow, 1, sourceParent).internalId(), model->root());

if(!m_filter.isEmpty()) {
result &= checkClassTypeFilter(sourceRow, sourceParent);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ void ObjectSelectBrowser::setTypeFilter(const QString &filter) {

Object *ObjectSelectBrowser::findObject(uint32_t id) {
ObjectHierarchyModel *model = static_cast<ObjectHierarchyModel *>(m_componentProxy->sourceModel());
return model->findObject(id);
return Engine::findObject(id, model->root());
}

void ObjectSelectBrowser::expandToIndex(const QModelIndex &index, QTreeView *view) {
Expand Down

0 comments on commit 16ba4fd

Please sign in to comment.