diff --git a/include/mainwindow.h b/include/mainwindow.h index 8e999b24..397a1d72 100644 --- a/include/mainwindow.h +++ b/include/mainwindow.h @@ -417,6 +417,7 @@ private: void scrollMetatileSelectorToSelection(); MapListToolBar* getCurrentMapListToolBar(); MapTree* getCurrentMapList(); + void refreshLocationsComboBox(); QObjectList shortcutableObjects() const; void addCustomHeaderValue(QString key, QJsonValue value, bool isNew = false); diff --git a/include/project.h b/include/project.h index c99bd05b..efb7db7c 100644 --- a/include/project.h +++ b/include/project.h @@ -139,7 +139,8 @@ public: bool readSpeciesIconPaths(); QMap speciesToIconPath; - void addNewMapsec(QString name); + void addNewMapsec(const QString &name); + void removeMapsec(const QString &name); bool hasUnsavedChanges(); bool hasUnsavedDataChanges = false; @@ -266,6 +267,7 @@ private: signals: void fileChanged(QString filepath); + void mapSectionIdNamesChanged(); void mapLoaded(Map *map); }; diff --git a/include/ui/maplistmodels.h b/include/ui/maplistmodels.h index 3e6e95d1..80a5423b 100644 --- a/include/ui/maplistmodels.h +++ b/include/ui/maplistmodels.h @@ -65,9 +65,11 @@ public: ~MapListModel() { } virtual QModelIndex indexOf(QString id) const = 0; - virtual void removeFolder(int index) = 0; - virtual void removeItem(const QModelIndex &index); + virtual void removeItemAt(const QModelIndex &index); virtual QStandardItem *getItem(const QModelIndex &index) const = 0; + +protected: + virtual void removeItem(QStandardItem *item) = 0; }; class MapGroupModel : public MapListModel { @@ -94,13 +96,15 @@ public: QStandardItem *insertGroupItem(QString groupName); QStandardItem *insertMapItem(QString mapName, QString groupName); - virtual void removeFolder(int index) override; virtual QStandardItem *getItem(const QModelIndex &index) const override; virtual QModelIndex indexOf(QString mapName) const override; void initialize(); +protected: + virtual void removeItem(QStandardItem *item) override; + private: friend class MapTree; void updateProject(); @@ -137,13 +141,15 @@ public: QStandardItem *insertAreaItem(QString areaName); QStandardItem *insertMapItem(QString mapName, QString areaName, int groupIndex); - virtual void removeFolder(int index) override; virtual QStandardItem *getItem(const QModelIndex &index) const override; virtual QModelIndex indexOf(QString mapName) const override; void initialize(); +protected: + virtual void removeItem(QStandardItem *item) override; + private: Project *project; QStandardItem *root = nullptr; @@ -176,13 +182,15 @@ public: QStandardItem *insertLayoutItem(QString layoutId); QStandardItem *insertMapItem(QString mapName, QString layoutId); - virtual void removeFolder(int index) override; virtual QStandardItem *getItem(const QModelIndex &index) const override; virtual QModelIndex indexOf(QString layoutName) const override; void initialize(); +protected: + virtual void removeItem(QStandardItem *item) override; + private: Project *project; QStandardItem *root = nullptr; diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 90b2a80c..9cb9d130 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -598,8 +598,9 @@ bool MainWindow::openProject(QString dir, bool initial) { // Create the project auto project = new Project(editor); project->set_root(dir); - QObject::connect(project, &Project::fileChanged, this, &MainWindow::showFileWatcherWarning); - QObject::connect(project, &Project::mapLoaded, this, &MainWindow::onMapLoaded); + connect(project, &Project::fileChanged, this, &MainWindow::showFileWatcherWarning); + connect(project, &Project::mapLoaded, this, &MainWindow::onMapLoaded); + connect(project, &Project::mapSectionIdNamesChanged, this, &MainWindow::refreshLocationsComboBox); this->editor->setProject(project); // Make sure project looks reasonable before attempting to load it @@ -1163,7 +1164,6 @@ bool MainWindow::setProjectUI() { // Block signals to the comboboxes while they are being modified const QSignalBlocker blocker1(ui->comboBox_Song); - const QSignalBlocker blocker2(ui->comboBox_Location); const QSignalBlocker blocker3(ui->comboBox_PrimaryTileset); const QSignalBlocker blocker4(ui->comboBox_SecondaryTileset); const QSignalBlocker blocker5(ui->comboBox_Weather); @@ -1176,8 +1176,6 @@ bool MainWindow::setProjectUI() { // Set up project comboboxes ui->comboBox_Song->clear(); ui->comboBox_Song->addItems(project->songNames); - ui->comboBox_Location->clear(); - ui->comboBox_Location->addItems(project->mapSectionIdNames); ui->comboBox_PrimaryTileset->clear(); ui->comboBox_PrimaryTileset->addItems(project->primaryTilesetLabels); ui->comboBox_SecondaryTileset->clear(); @@ -1198,6 +1196,7 @@ bool MainWindow::setProjectUI() { ui->comboBox_EmergeMap->addItems(project->mapNames); ui->comboBox_EmergeMap->setClearButtonEnabled(true); ui->comboBox_EmergeMap->setFocusedScrollingEnabled(false); + refreshLocationsComboBox(); // Show/hide parts of the UI that are dependent on the user's project settings @@ -1247,6 +1246,17 @@ bool MainWindow::setProjectUI() { return true; } +void MainWindow::refreshLocationsComboBox() { + QStringList locations = this->editor->project->mapSectionIdNames; + locations.sort(); + + const QSignalBlocker b(ui->comboBox_Location); + ui->comboBox_Location->clear(); + ui->comboBox_Location->addItems(locations); + if (this->editor->map) + ui->comboBox_Location->setCurrentText(this->editor->map->location); +} + void MainWindow::clearProjectUI() { // Block signals to the comboboxes while they are being modified const QSignalBlocker blocker1(ui->comboBox_Song); @@ -1328,19 +1338,30 @@ void MainWindow::onOpenMapListContextMenu(const QPoint &point) { QMenu menu(this); QAction* addToFolderAction = nullptr; QAction* deleteFolderAction = nullptr; + QAction* openItemAction = nullptr; if (itemType == "map_name") { // Right-clicking on a map. - // TODO: Add action to delete map once deleting maps is supported + openItemAction = menu.addAction("Open Map"); + //menu.addSeparator(); + //connect(menu.addAction("Delete Map"), &QAction::triggered, [this, index] { deleteMapListItem(index); }); // TODO: No support for deleting maps } else if (itemType == "map_group") { // Right-clicking on a map group folder addToFolderAction = menu.addAction("Add New Map to Group"); + menu.addSeparator(); 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"); + menu.addSeparator(); + deleteFolderAction = menu.addAction("Delete Area"); + if (itemName == this->editor->project->getEmptyMapsecName()) + deleteFolderAction->setEnabled(false); // Disallow deleting the default name } else if (itemType == "map_layout") { // Right-clicking on a map layout + openItemAction = menu.addAction("Open Layout"); addToFolderAction = menu.addAction("Add New Map with Layout"); + //menu.addSeparator(); + //deleteFolderAction = menu.addAction("Delete Layout"); // TODO: No support for deleting layouts } if (addToFolderAction) { @@ -1351,13 +1372,16 @@ void MainWindow::onOpenMapListContextMenu(const QPoint &point) { } if (deleteFolderAction) { connect(deleteFolderAction, &QAction::triggered, [sourceModel, index] { - sourceModel->removeFolder(index.row()); + sourceModel->removeItemAt(index); }); 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); } } + if (openItemAction) { + connect(openItemAction, &QAction::triggered, [this, index] { openMapListItem(index); }); + } if (menu.actions().length() != 0) menu.exec(QCursor::pos()); diff --git a/src/project.cpp b/src/project.cpp index 9d87c6f4..9c9fcf14 100644 --- a/src/project.cpp +++ b/src/project.cpp @@ -2319,7 +2319,7 @@ QString Project::getEmptyMapsecName() { } // This function assumes a valid and unique name -void Project::addNewMapsec(QString name) { +void Project::addNewMapsec(const QString &name) { if (!this->mapSectionIdNames.isEmpty() && this->mapSectionIdNames.last() == getEmptyMapsecName()) { // If the default map section name (MAPSEC_NONE) is last in the list we'll keep it last in the list. this->mapSectionIdNames.insert(this->mapSectionIdNames.length() - 1, name); @@ -2327,6 +2327,16 @@ void Project::addNewMapsec(QString name) { this->mapSectionIdNames.append(name); } this->hasUnsavedDataChanges = true; + emit mapSectionIdNamesChanged(); +} + +void Project::removeMapsec(const QString &name) { + if (!this->mapSectionIdNames.contains(name) || name == getEmptyMapsecName()) + return; + + this->mapSectionIdNames.removeOne(name); + this->hasUnsavedDataChanges = true; + emit mapSectionIdNamesChanged(); } // Read the constants to preserve any "unused" heal locations when writing the file later diff --git a/src/ui/maplistmodels.cpp b/src/ui/maplistmodels.cpp index 616e608c..a270736a 100644 --- a/src/ui/maplistmodels.cpp +++ b/src/ui/maplistmodels.cpp @@ -31,14 +31,14 @@ void MapTree::keyPressEvent(QKeyEvent *event) { persistentIndexes.append(model->mapToSource(index)); } for (const auto &index : persistentIndexes) { - sourceModel->removeItem(index); + sourceModel->removeItemAt(index); } } else { QWidget::keyPressEvent(event); } } -void MapListModel::removeItem(const QModelIndex &index) { +void MapListModel::removeItemAt(const QModelIndex &index) { QStandardItem *item = this->getItem(index)->child(index.row(), index.column()); if (!item) return; @@ -49,7 +49,7 @@ void MapListModel::removeItem(const QModelIndex &index) { } else { // TODO: Because there's no support for deleting maps we can only delete empty folders if (!item->hasChildren()) { - this->removeFolder(index.row()); + this->removeItem(item); } } } @@ -282,8 +282,8 @@ QStandardItem *MapGroupModel::insertGroupItem(QString groupName) { return group; } -void MapGroupModel::removeFolder(int index) { - this->removeRow(index); +void MapGroupModel::removeItem(QStandardItem *item) { + this->removeRow(item->row()); this->updateProject(); } @@ -454,10 +454,9 @@ QStandardItem *MapAreaModel::insertMapItem(QString mapName, QString areaName, in return map; } -// Note: Not actually supported in the interface at the moment. -void MapAreaModel::removeFolder(int index) { - this->removeRow(index); - this->project->mapSectionIdNames.removeAt(index); +void MapAreaModel::removeItem(QStandardItem *item) { + this->project->removeMapsec(item->data(Qt::UserRole).toString()); + this->removeRow(item->row()); } void MapAreaModel::initialize() { @@ -612,7 +611,7 @@ QStandardItem *LayoutTreeModel::insertMapItem(QString mapName, QString layoutId) return map; } -void LayoutTreeModel::removeFolder(int) { +void LayoutTreeModel::removeItem(QStandardItem *) { // TODO: Deleting layouts not supported } diff --git a/src/ui/newmappopup.cpp b/src/ui/newmappopup.cpp index 261544f2..def485c2 100644 --- a/src/ui/newmappopup.cpp +++ b/src/ui/newmappopup.cpp @@ -8,6 +8,8 @@ #include #include +// TODO: Convert to modal dialog (among other things, this means we wouldn't need to worry about changes to the map list while this is open) + struct NewMapPopup::Settings NewMapPopup::settings = {}; NewMapPopup::NewMapPopup(QWidget *parent, Project *project) :