diff --git a/forms/newlayoutdialog.ui b/forms/newlayoutdialog.ui index d285bdb1..bfbc9b02 100644 --- a/forms/newlayoutdialog.ui +++ b/forms/newlayoutdialog.ui @@ -25,7 +25,7 @@ 0 0 238 - 106 + 107 @@ -56,6 +56,9 @@ <html><head/><body><p>The constant that will be used to refer to this layout. It cannot be the same as any other existing layout.</p></body></html> + + true + diff --git a/include/mainwindow.h b/include/mainwindow.h index c51b10cf..1e8c53bb 100644 --- a/include/mainwindow.h +++ b/include/mainwindow.h @@ -349,7 +349,9 @@ private: void clearProjectUI(); void openNewMapDialog(); + void openDuplicateMapDialog(const QString &mapName); void openNewLayoutDialog(); + void openDuplicateLayoutDialog(const QString &layoutId); void openSubWindow(QWidget * window); void scrollMapList(MapTree *list, const QString &itemName); void scrollMapListToCurrentMap(MapTree *list); @@ -360,6 +362,7 @@ private: bool openProject(QString dir, bool initial = false); bool closeProject(); void showProjectOpenFailure(); + void showMapsExcludedAlert(const QStringList &excludedMapNames); bool setInitialMap(); void saveGlobalConfigs(); @@ -408,7 +411,7 @@ private: void scrollMetatileSelectorToSelection(); MapListToolBar* getCurrentMapListToolBar(); MapTree* getCurrentMapList(); - void refreshLocationsComboBox(); + void setLocationComboBoxes(const QStringList &locations); QObjectList shortcutableObjects() const; void addCustomHeaderValue(QString key, QJsonValue value, bool isNew = false); diff --git a/include/project.h b/include/project.h index 8a08cef6..895f9979 100644 --- a/include/project.h +++ b/include/project.h @@ -280,6 +280,7 @@ signals: void mapGroupAdded(const QString &groupName); void mapSectionAdded(const QString &idName); void mapSectionIdNamesChanged(const QStringList &idNames); + void mapsExcluded(const QStringList &excludedMapNames); }; #endif // PROJECT_H diff --git a/include/ui/regionmapeditor.h b/include/ui/regionmapeditor.h index c1941651..d5269548 100644 --- a/include/ui/regionmapeditor.h +++ b/include/ui/regionmapeditor.h @@ -44,6 +44,8 @@ public: bool reconfigure(); + void setLocations(const QStringList &locations); + QObjectList shortcutableObjects() const; public slots: diff --git a/src/core/regionmap.cpp b/src/core/regionmap.cpp index 94650ccd..587be33c 100644 --- a/src/core/regionmap.cpp +++ b/src/core/regionmap.cpp @@ -397,10 +397,15 @@ void RegionMap::saveLayout() { case LayoutFormat::Binary: { QByteArray data; + int defaultValue = this->project->mapSectionIdNames.indexOf(this->default_map_section); for (int m = 0; m < this->layout_height; m++) { for (int n = 0; n < this->layout_width; n++) { int i = n + this->layout_width * m; - data.append(this->project->mapSectionIdNames.indexOf(this->layouts["main"][i].map_section)); + int mapSectionValue = this->project->mapSectionIdNames.indexOf(this->layouts["main"][i].map_section); + if (mapSectionValue < 0){ + mapSectionValue = defaultValue; + } + data.append(mapSectionValue); } } QFile bfile(fullPath(this->layout_path)); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 71484f2f..e006ed9a 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -627,7 +627,8 @@ bool MainWindow::openProject(QString dir, bool initial) { connect(project, &Project::tilesetCreated, this, &MainWindow::onNewTilesetCreated); connect(project, &Project::mapGroupAdded, this, &MainWindow::onNewMapGroupCreated); connect(project, &Project::mapSectionAdded, this, &MainWindow::onNewMapSectionCreated); - connect(project, &Project::mapSectionIdNamesChanged, this->mapHeaderForm, &MapHeaderForm::setLocations); + connect(project, &Project::mapSectionIdNamesChanged, this, &MainWindow::setLocationComboBoxes); + connect(project, &Project::mapsExcluded, this, &MainWindow::showMapsExcludedAlert); this->editor->setProject(project); // Make sure project looks reasonable before attempting to load it @@ -702,6 +703,22 @@ void MainWindow::showProjectOpenFailure() { error.exec(); } +// Alert the user that one or more maps have been excluded while loading the project. +void MainWindow::showMapsExcludedAlert(const QStringList &excludedMapNames) { + QMessageBox msgBox(QMessageBox::Icon::Warning, "porymap", "", QMessageBox::Ok, this); + + QString errorMsg; + if (excludedMapNames.length() == 1) { + errorMsg = QString("Failed to load map '%1'. Saving will exclude this map from your project.").arg(excludedMapNames.first()); + } else { + errorMsg = QString("Failed to load the maps listed below. Saving will exclude these maps from your project."); + msgBox.setDetailedText(excludedMapNames.join("\n")); + } + errorMsg.append(QString("\n\nPlease see %1 for full error details.").arg(getLogPath())); + msgBox.setText(errorMsg); + msgBox.exec(); +} + bool MainWindow::isProjectOpen() { return editor && editor->project; } @@ -861,19 +878,23 @@ bool MainWindow::userSetMap(QString map_name) { return true; // Already set if (map_name == editor->project->getDynamicMapName()) { - QMessageBox msgBox(this); - QString errorMsg = QString("The map '%1' can't be opened, it's a placeholder to indicate the specified map will be set programmatically.").arg(map_name); - msgBox.warning(nullptr, "Cannot Open Map", errorMsg); + QMessageBox msgBox(QMessageBox::Icon::Warning, + "Cannot Open Map", + QString("The map '%1' can't be opened, it's a placeholder to indicate the specified map will be set programmatically.").arg(map_name), + QMessageBox::Ok, + this); + msgBox.exec(); return false; } if (!setMap(map_name)) { - QMessageBox msgBox(this); - QString errorMsg = QString("There was an error opening map %1. Please see %2 for full error details.\n\n%3") - .arg(map_name) - .arg(getLogPath()) - .arg(getMostRecentError()); - msgBox.critical(nullptr, "Error Opening Map", errorMsg); + QMessageBox msgBox(QMessageBox::Icon::Critical, + "Error Opening Map", + QString("There was an error opening map %1.\n\nPlease see %2 for full error details.").arg(map_name).arg(getLogPath()), + QMessageBox::Ok, + this); + msgBox.setDetailedText(getMostRecentError()); + msgBox.exec(); return false; } return true; @@ -929,12 +950,13 @@ void MainWindow::setLayoutOnlyMode(bool layoutOnly) { // Use when the user is specifically requesting a layout to open. bool MainWindow::userSetLayout(QString layoutId) { if (!setLayout(layoutId)) { - QMessageBox msgBox(this); - QString errorMsg = QString("There was an error opening layout %1. Please see %2 for full error details.\n\n%3") - .arg(layoutId) - .arg(getLogPath()) - .arg(getMostRecentError()); - msgBox.critical(nullptr, "Error Opening Layout", errorMsg); + QMessageBox msgBox(QMessageBox::Icon::Critical, + "Error Opening Layout", + QString("There was an error opening layout %1.\n\nPlease see %2 for full error details.").arg(layoutId).arg(getLogPath()), + QMessageBox::Ok, + this); + msgBox.setDetailedText(getMostRecentError()); + msgBox.exec(); return false; } @@ -1217,8 +1239,7 @@ void MainWindow::onOpenMapListContextMenu(const QPoint &point) { copyToolTipAction = menu.addAction("Copy Map ID"); menu.addSeparator(); connect(menu.addAction("Duplicate Map"), &QAction::triggered, [this, itemName] { - auto dialog = new NewMapDialog(this->editor->project, this->editor->project->getMap(itemName), this); - dialog->open(); + openDuplicateMapDialog(itemName); }); //menu.addSeparator(); //connect(menu.addAction("Delete Map"), &QAction::triggered, [this, index] { deleteMapListItem(index); }); // TODO: No support for deleting maps @@ -1244,12 +1265,7 @@ void MainWindow::onOpenMapListContextMenu(const QPoint &point) { copyToolTipAction = menu.addAction("Copy Layout ID"); menu.addSeparator(); connect(menu.addAction("Duplicate Layout"), &QAction::triggered, [this, itemName] { - auto layout = this->editor->project->loadLayout(itemName); - if (layout) { - auto dialog = new NewLayoutDialog(this->editor->project, layout, this); - connect(dialog, &NewLayoutDialog::applied, this, &MainWindow::userSetLayout); - dialog->open(); - } + openDuplicateLayoutDialog(itemName); }); addToFolderAction = menu.addAction("Add New Map with Layout"); //menu.addSeparator(); @@ -1436,8 +1452,12 @@ void MainWindow::onNewMapGroupCreated(const QString &groupName) { void MainWindow::onNewMapSectionCreated(const QString &idName) { // Add new map section to the Areas map list view this->mapAreaModel->insertMapFolderItem(idName); +} - // TODO: Refresh Region Map Editor's map section dropdown, if it's open +void MainWindow::setLocationComboBoxes(const QStringList &locations) { + this->mapHeaderForm->setLocations(locations); + if (this->regionMapEditor) + this->regionMapEditor->setLocations(locations); } void MainWindow::onNewTilesetCreated(Tileset *tileset) { @@ -1460,12 +1480,33 @@ void MainWindow::openNewMapDialog() { dialog->open(); } +void MainWindow::openDuplicateMapDialog(const QString &mapName) { + const Map *map = this->editor->project->getMap(mapName); + if (map) { + auto dialog = new NewMapDialog(this->editor->project, map, this); + dialog->open(); + } else { + //TODO + } +} + void MainWindow::openNewLayoutDialog() { auto dialog = new NewLayoutDialog(this->editor->project, this); connect(dialog, &NewLayoutDialog::applied, this, &MainWindow::userSetLayout); dialog->open(); } +void MainWindow::openDuplicateLayoutDialog(const QString &layoutId) { + auto layout = this->editor->project->loadLayout(layoutId); + if (layout) { + auto dialog = new NewLayoutDialog(this->editor->project, layout, this); + connect(dialog, &NewLayoutDialog::applied, this, &MainWindow::userSetLayout); + dialog->open(); + } else { + //TODO + } +} + void MainWindow::on_actionNew_Tileset_triggered() { auto dialog = new NewTilesetDialog(editor->project, this); dialog->open(); diff --git a/src/project.cpp b/src/project.cpp index e7fc3ab2..578d20d2 100644 --- a/src/project.cpp +++ b/src/project.cpp @@ -406,10 +406,10 @@ Map *Project::createNewMap(const Project::NewMapSettings &settings, const Map* t mapNamePos = this->mapNames.length(); } - if (!this->mapSectionIdNames.contains(map->header()->location())) { + const QString location = map->header()->location(); + if (!this->mapSectionIdNames.contains(location) && isIdentifierUnique(location)) { // Unrecognized MAPSEC value. Add it. - // TODO: Validate location before adding - addNewMapsec(map->header()->location()); + addNewMapsec(location); } this->mapNames.insert(mapNamePos, map->name()); @@ -492,15 +492,12 @@ bool Project::loadLayout(Layout *layout) { } Layout *Project::loadLayout(QString layoutId) { - if (this->mapLayouts.contains(layoutId)) { - Layout *layout = this->mapLayouts[layoutId]; - if (loadLayout(layout)) { - return layout; - } + Layout *layout = this->mapLayouts.value(layoutId); + if (!layout || !loadLayout(layout)) { + logError(QString("Failed to load layout '%1'").arg(layoutId)); + return nullptr; } - - logError(QString("Failed to load layout '%1'").arg(layoutId)); - return nullptr; + return layout; } bool Project::loadMapLayout(Map* map) { @@ -508,12 +505,12 @@ bool Project::loadMapLayout(Map* map) { return true; } - if (this->mapLayouts.contains(map->layoutId())) { - map->setLayout(this->mapLayouts[map->layoutId()]); - } else { + Layout *layout = this->mapLayouts.value(map->layoutId()); + if (!layout) { logError(QString("Map '%1' has an unknown layout '%2'").arg(map->name()).arg(map->layoutId())); return false; } + map->setLayout(layout); if (map->hasUnsavedChanges()) { return true; @@ -558,24 +555,11 @@ bool Project::readMapLayouts() { .arg(layoutsLabel)); } - static const QList requiredFields = QList{ - "id", - "name", - "width", - "height", - "primary_tileset", - "secondary_tileset", - "border_filepath", - "blockdata_filepath", - }; + QStringList failedLayoutNames; // TODO: Populate for (int i = 0; i < layouts.size(); i++) { QJsonObject layoutObj = layouts[i].toObject(); if (layoutObj.isEmpty()) continue; - if (!parser.ensureFieldsExist(layoutObj, requiredFields)) { - logError(QString("Layout %1 is missing field(s) in %2.").arg(i).arg(layoutsFilepath)); - return false; - } Layout *layout = new Layout(); layout->id = ParseUtil::jsonToQString(layoutObj["id"]); if (layout->id.isEmpty()) { @@ -611,15 +595,11 @@ bool Project::readMapLayouts() { if (projectConfig.useCustomBorderSize) { int bwidth = ParseUtil::jsonToInt(layoutObj["border_width"]); if (bwidth <= 0) { // 0 is an expected border width/height that should be handled, GF used it for the RS layouts in FRLG - logWarn(QString("Invalid 'border_width' value '%1' for %2 in %3. Must be greater than 0. Using default (%4) instead.") - .arg(bwidth).arg(layout->id).arg(layoutsFilepath).arg(DEFAULT_BORDER_WIDTH)); bwidth = DEFAULT_BORDER_WIDTH; } layout->border_width = bwidth; int bheight = ParseUtil::jsonToInt(layoutObj["border_height"]); if (bheight <= 0) { - logWarn(QString("Invalid 'border_height' value '%1' for %2 in %3. Must be greater than 0. Using default (%4) instead.") - .arg(bheight).arg(layout->id).arg(layoutsFilepath).arg(DEFAULT_BORDER_HEIGHT)); bheight = DEFAULT_BORDER_HEIGHT; } layout->border_height = bheight; @@ -1817,8 +1797,10 @@ bool Project::readMapGroups() { QJsonArray mapGroupOrder = mapGroupsObj["group_order"].toArray(); const QString dynamicMapName = getDynamicMapName(); + const QString dynamicMapConstant = getDynamicMapDefineName(); // Process the map group lists + QStringList failedMapNames; for (int groupIndex = 0; groupIndex < mapGroupOrder.size(); groupIndex++) { const QString groupName = ParseUtil::jsonToQString(mapGroupOrder.at(groupIndex)); const QJsonArray mapNamesJson = mapGroupsObj.value(groupName).toArray(); @@ -1829,45 +1811,73 @@ bool Project::readMapGroups() { const QString mapName = ParseUtil::jsonToQString(mapNamesJson.at(j)); if (mapName == dynamicMapName) { logWarn(QString("Ignoring map with reserved name '%1'.").arg(mapName)); + failedMapNames.append(mapName); continue; } if (this->mapNames.contains(mapName)) { logWarn(QString("Ignoring repeated map name '%1'.").arg(mapName)); + failedMapNames.append(mapName); continue; } // Load the map's json file so we can get its ID constant (and two other constants we use for the map list). QJsonDocument mapDoc; - if (!readMapJson(mapName, &mapDoc)) + if (!readMapJson(mapName, &mapDoc)) { + failedMapNames.append(mapName); continue; // Error message has already been logged + } // Read and validate the map's ID from its JSON data. const QJsonObject mapObj = mapDoc.object(); const QString mapConstant = ParseUtil::jsonToQString(mapObj["id"]); if (mapConstant.isEmpty()) { logWarn(QString("Map '%1' is missing an \"id\" value and will be ignored.").arg(mapName)); + failedMapNames.append(mapName); + continue; + } + if (mapConstant == dynamicMapConstant) { + logWarn(QString("Ignoring map with reserved \"id\" value '%1'.").arg(mapName)); + failedMapNames.append(mapName); continue; } const QString expectedPrefix = projectConfig.getIdentifier(ProjectIdentifier::define_map_prefix); if (!mapConstant.startsWith(expectedPrefix)) { logWarn(QString("Map '%1' has invalid \"id\" value '%2' and will be ignored. Value must begin with '%3'.").arg(mapName).arg(mapConstant).arg(expectedPrefix)); + failedMapNames.append(mapName); continue; } auto it = this->mapConstantsToMapNames.constFind(mapConstant); if (it != this->mapConstantsToMapNames.constEnd()) { logWarn(QString("Map '%1' has the same \"id\" value '%2' as map '%3' and will be ignored.").arg(mapName).arg(it.key()).arg(it.value())); + failedMapNames.append(mapName); continue; } + // Read layout ID for map list + const QString layoutId = ParseUtil::jsonToQString(mapObj["layout"]); + if (!this->layoutIds.contains(layoutId)) { + // If a map has an unknown layout ID it won't be able to load it at all anyway, so skip it. + // Skipping these will let us assume all the map layout IDs are valid, which simplies some handling elsewhere. + logWarn(QString("Map '%1' has unknown \"layout\" value '%2' and will be ignored.").arg(mapName).arg(layoutId)); + failedMapNames.append(mapName); + continue; + } + + // Read MAPSEC name for map list + const QString mapSectionName = ParseUtil::jsonToQString(mapObj["region_map_section"]); + if (!this->mapSectionIdNames.contains(mapSectionName)) { + // An unknown location is OK. Aside from that name not appearing in the dropdowns this shouldn't cause problems. + // We'll log a warning, but allow this map to be displayed. + logWarn(QString("Map '%1' has unknown \"region_map_section\" value '%2'.").arg(mapName).arg(mapSectionName)); + } + // Success, save the constants to the project this->mapNames.append(mapName); this->groupNameToMapNames[groupName].append(mapName); - // TODO: These are not well-kept in sync (and that's probably a bad design indication. Maybe Maps should have a not-fully-loaded state, but have all their map.json data cached) this->mapConstantsToMapNames.insert(mapConstant, mapName); this->mapNamesToMapConstants.insert(mapName, mapConstant); - // TODO: Either verify that these are known IDs, or make sure nothing breaks when they're unknown. - this->mapNameToLayoutId.insert(mapName, ParseUtil::jsonToQString(mapObj["layout"])); - this->mapNameToMapSectionName.insert(mapName, ParseUtil::jsonToQString(mapObj["region_map_section"])); + this->mapNameToLayoutId.insert(mapName, layoutId); + this->mapNameToMapSectionName.insert(mapName, mapSectionName); } } @@ -1880,10 +1890,15 @@ bool Project::readMapGroups() { return false; } + if (!failedMapNames.isEmpty()) { + // At least 1 map was excluded due to an error. + // User should be alerted of this, rather than just silently logging the details. + emit mapsExcluded(failedMapNames); + } + // Save special "Dynamic" constant - const QString defineName = this->getDynamicMapDefineName(); - this->mapConstantsToMapNames.insert(defineName, dynamicMapName); - this->mapNamesToMapConstants.insert(dynamicMapName, defineName); + this->mapConstantsToMapNames.insert(dynamicMapConstant, dynamicMapName); + this->mapNamesToMapConstants.insert(dynamicMapName, dynamicMapConstant); this->mapNames.append(dynamicMapName); return true; @@ -2274,10 +2289,18 @@ bool Project::readRegionMapSections() { QJsonObject mapSectionObj = mapSections.at(i).toObject(); // For each map section, "id" is the only required field. This is the field we use to display the location names in the map list, and in various drop-downs. - const QString idField = "id"; + QString idField = "id"; if (!mapSectionObj.contains(idField)) { - logWarn(QString("Ignoring data for map section %1 in '%2'. Missing required field \"%3\"").arg(i).arg(baseFilepath).arg(idField)); - continue; + const QString oldIdField = "map_section"; + if (mapSectionObj.contains(oldIdField)) { + // User has the old name for this field. Parse using this name, then save with the new name. + // This will presumably stop the user's project from compiling, but that's preferable to + // ignoring everything here and then wiping the file's data when we save later. + idField = oldIdField; + } else { + logWarn(QString("Ignoring data for map section %1 in '%2'. Missing required field \"%3\"").arg(i).arg(baseFilepath).arg(idField)); + continue; + } } const QString idName = ParseUtil::jsonToQString(mapSectionObj[idField]); if (!idName.startsWith(requiredPrefix)) { @@ -2338,7 +2361,6 @@ void Project::addNewMapsec(const QString &name) { } this->hasUnsavedDataChanges = true; - // TODO: Simplify into a single signal that updates the map list only if necessary emit mapSectionAdded(name); emit mapSectionIdNamesChanged(this->mapSectionIdNames); } diff --git a/src/scriptapi/apimap.cpp b/src/scriptapi/apimap.cpp index 91cc4e67..2532f132 100644 --- a/src/scriptapi/apimap.cpp +++ b/src/scriptapi/apimap.cpp @@ -832,10 +832,6 @@ QString MainWindow::getLocation() { void MainWindow::setLocation(QString location) { if (!this->editor || !this->editor->map || !this->editor->project) return; - if (!this->editor->project->mapSectionIdNames.contains(location)) { - logError(QString("Unknown location '%1'").arg(location)); - return; - } this->editor->map->header()->setLocation(location); } diff --git a/src/ui/mapheaderform.cpp b/src/ui/mapheaderform.cpp index 6f6e4dec..7aa5a628 100644 --- a/src/ui/mapheaderform.cpp +++ b/src/ui/mapheaderform.cpp @@ -55,7 +55,11 @@ void MapHeaderForm::init(const Project * project) { ui->comboBox_BattleScene->clear(); ui->comboBox_BattleScene->addItems(project->mapBattleScenes); - setLocations(project->mapSectionIdNames); + QStringList locations = project->mapSectionIdNames; + locations.sort(); + const QSignalBlocker b_Locations(ui->comboBox_Location); + ui->comboBox_Location->clear(); + ui->comboBox_Location->addItems(locations); // Hide config-specific settings @@ -72,8 +76,7 @@ void MapHeaderForm::init(const Project * project) { ui->label_FloorNumber->setVisible(floorNumEnabled); } -// This combo box is treated specially because (unlike the other combo boxes) -// items that should be in this drop-down can be added or removed externally. +// Unlike other combo boxes in the map header form, locations can be added or removed externally. void MapHeaderForm::setLocations(QStringList locations) { locations.sort(); diff --git a/src/ui/maplistmodels.cpp b/src/ui/maplistmodels.cpp index d6b20af9..0f352f4f 100644 --- a/src/ui/maplistmodels.cpp +++ b/src/ui/maplistmodels.cpp @@ -454,10 +454,11 @@ QStandardItem *LayoutTreeModel::createMapFolderItem(const QString &folderName, Q // Despite using layout IDs internally, the Layouts map list shows layouts using their file path name. // We could handle this with Qt::DisplayRole in LayoutTreeModel::data, but then it would be sorted using the ID instead of the name. const Layout* layout = this->project->mapLayouts.value(folderName); - if (layout) { - folder->setText(layout->name); - folder->setToolTip(layout->id); - } + if (layout) folder->setText(layout->name); + + // The layout ID will instead be shown as a tool tip. + folder->setToolTip(folderName); + return folder; } diff --git a/src/ui/regionmapeditor.cpp b/src/ui/regionmapeditor.cpp index c6485d51..cb0f6d44 100644 --- a/src/ui/regionmapeditor.cpp +++ b/src/ui/regionmapeditor.cpp @@ -651,10 +651,9 @@ void RegionMapEditor::displayRegionMapLayout() { void RegionMapEditor::displayRegionMapLayoutOptions() { if (!this->region_map->layoutEnabled()) return; - this->ui->comboBox_RM_ConnectedMap->blockSignals(true); + const QSignalBlocker b(ui->comboBox_RM_ConnectedMap); this->ui->comboBox_RM_ConnectedMap->clear(); this->ui->comboBox_RM_ConnectedMap->addItems(this->project->mapSectionIdNames); - this->ui->comboBox_RM_ConnectedMap->blockSignals(false); this->ui->frame_RM_Options->setEnabled(true); @@ -662,22 +661,19 @@ void RegionMapEditor::displayRegionMapLayoutOptions() { } void RegionMapEditor::updateRegionMapLayoutOptions(int index) { - this->ui->comboBox_RM_ConnectedMap->blockSignals(true); + const QSignalBlocker b_ConnectedMap(ui->comboBox_RM_ConnectedMap); this->ui->comboBox_RM_ConnectedMap->setCurrentText(this->region_map->squareMapSection(index)); - this->ui->comboBox_RM_ConnectedMap->blockSignals(false); this->ui->pushButton_RM_Options_delete->setEnabled(this->region_map->squareHasMap(index)); - this->ui->spinBox_RM_LayoutWidth->blockSignals(true); - this->ui->spinBox_RM_LayoutHeight->blockSignals(true); + const QSignalBlocker b_LayoutWidth(ui->spinBox_RM_LayoutWidth); + const QSignalBlocker b_LayoutHeight(ui->spinBox_RM_LayoutHeight); this->ui->spinBox_RM_LayoutWidth->setMinimum(1); this->ui->spinBox_RM_LayoutWidth->setMaximum(this->region_map->tilemapWidth() - this->region_map->padLeft()); this->ui->spinBox_RM_LayoutHeight->setMinimum(1); this->ui->spinBox_RM_LayoutHeight->setMaximum(this->region_map->tilemapHeight() - this->region_map->padTop()); this->ui->spinBox_RM_LayoutWidth->setValue(this->region_map->layoutWidth()); this->ui->spinBox_RM_LayoutHeight->setValue(this->region_map->layoutHeight()); - this->ui->spinBox_RM_LayoutWidth->blockSignals(false); - this->ui->spinBox_RM_LayoutHeight->blockSignals(false); } void RegionMapEditor::displayRegionMapEntriesImage() { @@ -1323,3 +1319,18 @@ void RegionMapEditor::on_verticalSlider_Zoom_Image_Tiles_valueChanged(int val) { ui->graphicsView_RegionMap_Tiles->setTransform(transform); ui->graphicsView_RegionMap_Tiles->setFixedSize(width + 2, height + 2); } + +// Repopulate the combo boxes that display MAPSEC names. +void RegionMapEditor::setLocations(const QStringList &locations) { + const QSignalBlocker b_ConnectedMap(ui->comboBox_RM_ConnectedMap); + auto before = ui->comboBox_RM_ConnectedMap->currentText(); + ui->comboBox_RM_ConnectedMap->clear(); + ui->comboBox_RM_ConnectedMap->addItems(locations); + ui->comboBox_RM_ConnectedMap->setCurrentText(before); + + const QSignalBlocker b_MapSection(ui->comboBox_RM_Entry_MapSection); + before = ui->comboBox_RM_Entry_MapSection->currentText(); + ui->comboBox_RM_Entry_MapSection->clear(); + ui->comboBox_RM_Entry_MapSection->addItems(locations); + ui->comboBox_RM_Entry_MapSection->setCurrentText(before); +}