Update map list delete functionality

This commit is contained in:
GriffinR 2024-10-29 22:18:16 -04:00
parent b89c1ddc80
commit 23e094d850
7 changed files with 127 additions and 132 deletions

View file

@ -383,9 +383,6 @@ private:
void mapListAddGroup(); void mapListAddGroup();
void mapListAddLayout(); void mapListAddLayout();
void mapListAddArea(); void mapListAddArea();
void mapListRemoveGroup();
void mapListRemoveArea();
void mapListRemoveLayout();
void openMapListItem(const QModelIndex &index); void openMapListItem(const QModelIndex &index);
void saveMapListTab(int index); void saveMapListTab(int index);
@ -424,6 +421,7 @@ private:
void redrawMetatileSelection(); void redrawMetatileSelection();
void scrollMetatileSelectorToSelection(); void scrollMetatileSelectorToSelection();
MapListToolBar* getCurrentMapListToolBar(); MapListToolBar* getCurrentMapListToolBar();
MapTree* getCurrentMapList();
QObjectList shortcutableObjects() const; QObjectList shortcutableObjects() const;
void addCustomHeaderValue(QString key, QJsonValue value, bool isNew = false); void addCustomHeaderValue(QString key, QJsonValue value, bool isNew = false);

View file

@ -26,8 +26,12 @@ public:
MapTree(QWidget *parent) : QTreeView(parent) { MapTree(QWidget *parent) : QTreeView(parent) {
this->setDropIndicatorShown(true); this->setDropIndicatorShown(true);
this->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont)); this->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
this->setFocusPolicy(Qt::StrongFocus);
} }
protected:
virtual void keyPressEvent(QKeyEvent *event) override;
public slots: public slots:
void removeSelected(); void removeSelected();
}; };
@ -61,6 +65,9 @@ public:
~MapListModel() { } ~MapListModel() { }
virtual QModelIndex indexOf(QString id) const = 0; virtual QModelIndex indexOf(QString id) const = 0;
virtual void removeFolder(int index) = 0;
virtual void removeItem(const QModelIndex &index);
virtual QStandardItem *getItem(const QModelIndex &index) const = 0;
}; };
class MapGroupModel : public MapListModel { class MapGroupModel : public MapListModel {
@ -87,9 +94,9 @@ public:
QStandardItem *insertGroupItem(QString groupName); QStandardItem *insertGroupItem(QString groupName);
QStandardItem *insertMapItem(QString mapName, QString groupName); QStandardItem *insertMapItem(QString mapName, QString groupName);
void removeGroup(int groupIndex); virtual void removeFolder(int index) override;
QStandardItem *getItem(const QModelIndex &index) const; virtual QStandardItem *getItem(const QModelIndex &index) const override;
virtual QModelIndex indexOf(QString mapName) const override; virtual QModelIndex indexOf(QString mapName) const override;
void initialize(); void initialize();
@ -130,9 +137,9 @@ public:
QStandardItem *insertAreaItem(QString areaName); QStandardItem *insertAreaItem(QString areaName);
QStandardItem *insertMapItem(QString mapName, QString areaName, int groupIndex); QStandardItem *insertMapItem(QString mapName, QString areaName, int groupIndex);
void removeArea(int groupIndex); virtual void removeFolder(int index) override;
QStandardItem *getItem(const QModelIndex &index) const; virtual QStandardItem *getItem(const QModelIndex &index) const override;
virtual QModelIndex indexOf(QString mapName) const override; virtual QModelIndex indexOf(QString mapName) const override;
void initialize(); void initialize();
@ -170,8 +177,9 @@ public:
QStandardItem *insertLayoutItem(QString layoutId); QStandardItem *insertLayoutItem(QString layoutId);
QStandardItem *insertMapItem(QString mapName, QString layoutId); QStandardItem *insertMapItem(QString mapName, QString layoutId);
virtual void removeFolder(int index) override;
QStandardItem *getItem(const QModelIndex &index) const; virtual QStandardItem *getItem(const QModelIndex &index) const override;
virtual QModelIndex indexOf(QString layoutName) const override; virtual QModelIndex indexOf(QString layoutName) const override;
void initialize(); void initialize();

View file

@ -24,7 +24,7 @@ public:
QString layoutId; QString layoutId;
void init(); void init();
void initUi(); void initUi();
void init(int tabIndex, QVariant data); void init(int tabIndex, QString data);
void init(Layout *); void init(Layout *);
static void setDefaultSettings(Project *project); static void setDefaultSettings(Project *project);

View file

@ -153,10 +153,11 @@ void MainWindow::initExtraShortcuts() {
shortcutDuplicate_Events->setObjectName("shortcutDuplicate_Events"); shortcutDuplicate_Events->setObjectName("shortcutDuplicate_Events");
shortcutDuplicate_Events->setWhatsThis("Duplicate Selected Event(s)"); shortcutDuplicate_Events->setWhatsThis("Duplicate Selected Event(s)");
auto *shortcutDelete_Object = new Shortcut( // TODO: Reimplement this using keyPressEvent on the relevant widgets. Otherwise it steals the key event from anything else trying to use delete.
/*auto *shortcutDelete_Object = new Shortcut(
{QKeySequence("Del"), QKeySequence("Backspace")}, this, SLOT(onDeleteKeyPressed())); {QKeySequence("Del"), QKeySequence("Backspace")}, this, SLOT(onDeleteKeyPressed()));
shortcutDelete_Object->setObjectName("shortcutDelete_Object"); shortcutDelete_Object->setObjectName("shortcutDelete_Object");
shortcutDelete_Object->setWhatsThis("Delete Selected Item(s)"); shortcutDelete_Object->setWhatsThis("Delete Selected Item(s)");*/
auto *shortcutToggle_Border = new Shortcut(QKeySequence(), ui->checkBox_ToggleBorder, SLOT(toggle())); auto *shortcutToggle_Border = new Shortcut(QKeySequence(), ui->checkBox_ToggleBorder, SLOT(toggle()));
shortcutToggle_Border->setObjectName("shortcutToggle_Border"); shortcutToggle_Border->setObjectName("shortcutToggle_Border");
@ -874,11 +875,6 @@ bool MainWindow::setMap(QString map_name) {
return false; return false;
} }
// TODO: Redundant?
if (editor->map && !editor->map->name.isNull()) {
ui->mapList->setExpanded(groupListProxyModel->mapFromSource(mapGroupModel->indexOf(map_name)), false);
}
setLayoutOnlyMode(false); setLayoutOnlyMode(false);
this->lastSelectedEvent.clear(); this->lastSelectedEvent.clear();
@ -1301,11 +1297,7 @@ void MainWindow::scrollMapList(MapTree *list, QString itemName) {
if (!list || itemName.isEmpty()) if (!list || itemName.isEmpty())
return; return;
auto model = static_cast<FilterChildrenProxyModel*>(list->model()); auto model = static_cast<FilterChildrenProxyModel*>(list->model());
if (!model)
return;
auto sourceModel = static_cast<MapListModel*>(model->sourceModel()); auto sourceModel = static_cast<MapListModel*>(model->sourceModel());
if (!sourceModel)
return;
QModelIndex sourceIndex = sourceModel->indexOf(itemName); QModelIndex sourceIndex = sourceModel->indexOf(itemName);
if (!sourceIndex.isValid()) if (!sourceIndex.isValid())
return; return;
@ -1332,66 +1324,53 @@ void MainWindow::scrollMapListToCurrentLayout(MapTree *list) {
} }
void MainWindow::onOpenMapListContextMenu(const QPoint &point) { void MainWindow::onOpenMapListContextMenu(const QPoint &point) {
QStandardItemModel *model; // Get selected item from list
int dataRole; auto list = getCurrentMapList();
FilterChildrenProxyModel *proxy; if (!list) return;
QTreeView *list; auto model = static_cast<FilterChildrenProxyModel*>(list->model());
QString actionText; QModelIndex index = model->mapToSource(list->indexAt(point));
if (!index.isValid()) return;
int currentTab = ui->mapListContainer->currentIndex(); auto sourceModel = static_cast<MapListModel*>(model->sourceModel());
QStandardItem *selectedItem = sourceModel->itemFromIndex(index);
switch (currentTab) { const QString itemType = selectedItem->data(MapListUserRoles::TypeRole).toString();
case MapListTab::Groups: const QString itemName = selectedItem->data(Qt::UserRole).toString();
model = this->mapGroupModel;
dataRole = MapListUserRoles::GroupRole;
proxy = this->groupListProxyModel;
list = this->ui->mapList;
actionText = "Add New Map to Group";
break;
case MapListTab::Areas:
model = this->mapAreaModel;
dataRole = Qt::UserRole;
proxy = this->areaListProxyModel;
list = this->ui->areaList;
actionText = "Add New Map to Area";
break;
case MapListTab::Layouts:
model = this->layoutTreeModel;
dataRole = Qt::UserRole;
proxy = this->layoutListProxyModel;
list = this->ui->layoutList;
actionText = "Add New Map with Layout";
break;
}
QModelIndex index = proxy->mapToSource(list->indexAt(point));
if (!index.isValid()) {
return;
}
QStandardItem *selectedItem = model->itemFromIndex(index);
if (selectedItem->parent()) {
// TODO: Right-click delete on maps?
return;
}
QVariant itemData = selectedItem->data(dataRole);
if (!itemData.isValid()) {
return;
}
QMenu menu(this); QMenu menu(this);
QActionGroup actions(&menu); QAction* addToFolderAction = nullptr;
actions.addAction(menu.addAction(actionText))->setData(itemData); QAction* deleteFolderAction = nullptr;
if (itemType == "map_name") {
// Right-clicking on a map.
// TODO: Add action to delete map once deleting maps is supported
} else if (itemType == "map_group") {
// Right-clicking on a map group folder
addToFolderAction = menu.addAction("Add New Map to Group");
deleteFolderAction = menu.addAction("Delete Map Group");
} else if (itemType == "map_section") {
// Right-clicking on an MAPSEC folder
addToFolderAction = menu.addAction("Add New Map to Area");
} else if (itemType == "map_layout") {
// Right-clicking on a map layout
addToFolderAction = menu.addAction("Add New Map with Layout");
}
auto triggeredAction = menu.exec(QCursor::pos()); if (addToFolderAction) {
if (!triggeredAction) connect(addToFolderAction, &QAction::triggered, [this, itemName] {
return; openNewMapPopupWindow();
this->newMapPrompt->init(ui->mapListContainer->currentIndex(), itemName);
});
}
if (deleteFolderAction) {
connect(deleteFolderAction, &QAction::triggered, [sourceModel, index] {
sourceModel->removeFolder(index.row());
});
if (selectedItem->hasChildren()){
// TODO: No support for deleting maps, so you may only delete folders if they don't contain any maps.
deleteFolderAction->setEnabled(false);
}
}
// At the moment all the actions do the same thing (add new map/layout). if (menu.actions().length() != 0)
openNewMapPopupWindow(); menu.exec(QCursor::pos());
this->newMapPrompt->init(currentTab, triggeredAction->data());
} }
void MainWindow::mapListAddGroup() { void MainWindow::mapListAddGroup() {
@ -1589,49 +1568,6 @@ void MainWindow::mapListAddArea() {
} }
} }
// TODO: Connect to right-click on map group folder in list
void MainWindow::mapListRemoveGroup() {
QItemSelectionModel *selectionModel = this->ui->mapList->selectionModel();
if (selectionModel->hasSelection()) {
QModelIndexList selectedIndexes = selectionModel->selectedRows();
for (QModelIndex proxyIndex : selectedIndexes) {
QModelIndex index = this->groupListProxyModel->mapToSource(proxyIndex);
QStandardItem *item = this->mapGroupModel->getItem(index)->child(index.row(), index.column());
if (!item) continue;
QString type = item->data(MapListUserRoles::TypeRole).toString();
if (type == "map_group" && !item->hasChildren()) {
QString groupName = item->data(Qt::UserRole).toString();
// delete empty group
this->mapGroupModel->removeGroup(index.row());
}
}
}
}
// TODO: Decide what to do about this. Currently unused.
void MainWindow::mapListRemoveArea() {
QItemSelectionModel *selectionModel = this->ui->areaList->selectionModel();
if (selectionModel->hasSelection()) {
QModelIndexList selectedIndexes = selectionModel->selectedRows();
for (QModelIndex proxyIndex : selectedIndexes) {
QModelIndex index = this->areaListProxyModel->mapToSource(proxyIndex);
QStandardItem *item = this->mapAreaModel->getItem(index)->child(index.row(), index.column());
if (!item) continue;
QString type = item->data(MapListUserRoles::TypeRole).toString();
if (type == "map_section" && !item->hasChildren()) {
QString groupName = item->data(Qt::UserRole).toString();
// delete empty section
this->mapAreaModel->removeArea(index.row());
}
}
}
}
// TODO: Connect to right-click on layout
void MainWindow::mapListRemoveLayout() {
// TODO: consider this in the future
}
void MainWindow::onNewMapCreated() { void MainWindow::onNewMapCreated() {
QString newMapName = this->newMapPrompt->map->name; QString newMapName = this->newMapPrompt->map->name;
int newMapGroup = this->newMapPrompt->group; int newMapGroup = this->newMapPrompt->group;
@ -3186,6 +3122,13 @@ MapListToolBar* MainWindow::getCurrentMapListToolBar() {
} }
} }
MapTree* MainWindow::getCurrentMapList() {
auto toolbar = getCurrentMapListToolBar();
if (toolbar)
return toolbar->list();
return nullptr;
}
// Clear the search filters on all the map lists. // Clear the search filters on all the map lists.
// When the search filter is cleared the map lists will (if possible) display the currently-selected map/layout. // When the search filter is cleared the map lists will (if possible) display the currently-selected map/layout.
void MainWindow::resetMapListFilters() { void MainWindow::resetMapListFilters() {

View file

@ -3001,15 +3001,15 @@ bool Project::hasUnsavedChanges() {
// Check layouts for unsaved changes // Check layouts for unsaved changes
for (auto i = this->mapLayouts.constBegin(); i != this->mapLayouts.constEnd(); i++) { for (auto i = this->mapLayouts.constBegin(); i != this->mapLayouts.constEnd(); i++) {
auto map = i.value(); auto layout = i.value();
if (map && map->hasUnsavedChanges()) if (layout && layout->hasUnsavedChanges())
return true; return true;
} }
// Check loaded maps for unsaved changes // Check loaded maps for unsaved changes
for (auto i = this->mapCache.constBegin(); i != this->mapCache.constEnd(); i++) { for (auto i = this->mapCache.constBegin(); i != this->mapCache.constEnd(); i++) {
auto layout = i.value(); auto map = i.value();
if (layout && layout->hasUnsavedChanges()) if (map && map->hasUnsavedChanges())
return true; return true;
} }
return false; return false;

View file

@ -15,6 +15,45 @@ void MapTree::removeSelected() {
} }
} }
void MapTree::keyPressEvent(QKeyEvent *event) {
if (event->key() == Qt::Key_Delete || event->key() == Qt::Key_Backspace) {
// Delete selected items in the tree
auto selectionModel = this->selectionModel();
if (!selectionModel->hasSelection())
return;
auto model = static_cast<FilterChildrenProxyModel*>(this->model());
auto sourceModel = static_cast<MapListModel*>(model->sourceModel());
QModelIndexList selectedIndexes = selectionModel->selectedRows();
QList<QPersistentModelIndex> persistentIndexes;
for (const auto &index : selectedIndexes) {
persistentIndexes.append(model->mapToSource(index));
}
for (const auto &index : persistentIndexes) {
sourceModel->removeItem(index);
}
} else {
QWidget::keyPressEvent(event);
}
}
void MapListModel::removeItem(const QModelIndex &index) {
QStandardItem *item = this->getItem(index)->child(index.row(), index.column());
if (!item)
return;
const QString type = item->data(MapListUserRoles::TypeRole).toString();
if (type == "map_name") {
// TODO: No support for deleting maps
} else {
// TODO: Because there's no support for deleting maps we can only delete empty folders
if (!item->hasChildren()) {
this->removeFolder(index.row());
}
}
}
QWidget *GroupNameDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &) const { QWidget *GroupNameDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &) const {
@ -244,8 +283,8 @@ QStandardItem *MapGroupModel::insertGroupItem(QString groupName) {
return group; return group;
} }
void MapGroupModel::removeGroup(int groupIndex) { void MapGroupModel::removeFolder(int index) {
this->removeRow(groupIndex); this->removeRow(index);
this->updateProject(); this->updateProject();
} }
@ -365,6 +404,8 @@ bool MapGroupModel::setData(const QModelIndex &index, const QVariant &value, int
} }
} }
// TODO: Deleting MAPSEC support? Currently it has no limits on drag/drop etc, so editing is disabled (so delete key from the map list is ignored)
// and it has no delete action in the context menu.
MapAreaModel::MapAreaModel(Project *project, QObject *parent) : MapListModel(parent) { MapAreaModel::MapAreaModel(Project *project, QObject *parent) : MapListModel(parent) {
@ -422,9 +463,9 @@ QStandardItem *MapAreaModel::insertMapItem(QString mapName, QString areaName, in
return map; return map;
} }
void MapAreaModel::removeArea(int areaIndex) { void MapAreaModel::removeFolder(int index) {
this->removeRow(areaIndex); this->removeRow(index);
this->project->mapSectionNameToValue.remove(this->project->mapSectionValueToName.take(areaIndex)); this->project->mapSectionNameToValue.remove(this->project->mapSectionValueToName.take(index));
} }
void MapAreaModel::initialize() { void MapAreaModel::initialize() {
@ -583,6 +624,11 @@ QStandardItem *LayoutTreeModel::insertMapItem(QString mapName, QString layoutId)
return map; return map;
} }
void LayoutTreeModel::removeFolder(int) {
// TODO: Deleting layouts not supported
}
void LayoutTreeModel::initialize() { void LayoutTreeModel::initialize() {
this->layoutItems.clear(); this->layoutItems.clear();
this->mapItems.clear(); this->mapItems.clear();

View file

@ -102,19 +102,19 @@ void NewMapPopup::init() {
} }
// Creating new map by right-clicking in the map list // Creating new map by right-clicking in the map list
void NewMapPopup::init(int tabIndex, QVariant data) { void NewMapPopup::init(int tabIndex, QString fieldName) {
initUi(); initUi();
switch (tabIndex) switch (tabIndex)
{ {
case MapListTab::Groups: case MapListTab::Groups:
settings.group = project->groupNames.at(data.toInt()); settings.group = fieldName;
break; break;
case MapListTab::Areas: case MapListTab::Areas:
settings.location = data.toString(); settings.location = fieldName;
break; break;
case MapListTab::Layouts: case MapListTab::Layouts:
this->ui->checkBox_UseExistingLayout->setCheckState(Qt::Checked); this->ui->checkBox_UseExistingLayout->setCheckState(Qt::Checked);
useLayout(data.toString()); useLayout(fieldName);
break; break;
} }
init(); init();