From 74e4e2647c280998a51c3a7118da73aab36adce5 Mon Sep 17 00:00:00 2001 From: garak Date: Fri, 16 Feb 2024 19:17:56 -0500 Subject: [PATCH] add new area (map section) functionality --- include/project.h | 6 ++++ include/ui/maplistmodels.h | 1 + src/mainwindow.cpp | 30 ++++++++++++++++- src/project.cpp | 66 ++++++++++++++++++++++++++++++++++++++ src/ui/maplistmodels.cpp | 8 +++++ 5 files changed, 110 insertions(+), 1 deletion(-) diff --git a/include/project.h b/include/project.h index 49bcd6aa..b8426453 100644 --- a/include/project.h +++ b/include/project.h @@ -80,6 +80,9 @@ public: QString importExportPath; QSet disabledSettingsNames; + // For files that are read and could contain extra text + QMap extraFileText; + void set_root(QString); void initSignals(); @@ -135,6 +138,8 @@ public: bool readSpeciesIconPaths(); QMap speciesToIconPath; + int appendMapsec(QString name); + QSet getTopLevelMapFields(); bool loadMapData(Map*); bool readMapLayouts(); @@ -159,6 +164,7 @@ public: void saveAllDataStructures(); void saveMapLayouts(); void saveMapGroups(); + void saveMapSections(); void saveWildMonData(); void saveMapConstantsHeader(); void saveHealLocations(Map*); diff --git a/include/ui/maplistmodels.h b/include/ui/maplistmodels.h index bb2fd07a..5787a622 100644 --- a/include/ui/maplistmodels.h +++ b/include/ui/maplistmodels.h @@ -117,6 +117,7 @@ public: QStandardItem *createAreaItem(QString areaName, int areaIndex); QStandardItem *createMapItem(QString mapName, int areaIndex, int mapIndex); + QStandardItem *insertAreaItem(QString areaName); QStandardItem *insertMapItem(QString mapName, QString areaName, int groupIndex); QStandardItem *getItem(const QModelIndex &index) const; diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 8a9f95b5..dc0ac54f 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1427,7 +1427,35 @@ void MainWindow::mapListAddLayout() { } void MainWindow::mapListAddArea() { - // this->mapAreaModel->insertMapItem(newMapName, newMap->location, newMapGroup); + // Note: there is no checking here for the limits on map section count + QDialog dialog(this, Qt::WindowTitleHint | Qt::WindowCloseButtonHint); + dialog.setWindowModality(Qt::ApplicationModal); + QDialogButtonBox newItemButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, &dialog); + connect(&newItemButtonBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject); + + QLineEdit *newNameEdit = new QLineEdit(&dialog); + newNameEdit->setText(projectConfig.getIdentifier(ProjectIdentifier::define_map_section_prefix)); + newNameEdit->setClearButtonEnabled(false); + + QRegularExpression re_validChars(QString("%1[_A-Za-z0-9]+$").arg(projectConfig.getIdentifier(ProjectIdentifier::define_map_section_prefix))); + QRegularExpressionValidator *validator = new QRegularExpressionValidator(re_validChars); + newNameEdit->setValidator(validator); + + connect(&newItemButtonBox, &QDialogButtonBox::accepted, [&](){ + if (!this->editor->project->mapSectionNameToValue.contains(newNameEdit->text())) + dialog.accept(); + }); + + QFormLayout form(&dialog); + + form.addRow("New Map Section Name", newNameEdit); + form.addRow(&newItemButtonBox); + + if (dialog.exec() == QDialog::Accepted) { + QString newFieldName = newNameEdit->text(); + if (newFieldName.isEmpty()) return; + this->mapAreaModel->insertAreaItem(newFieldName); + } } void MainWindow::mapListAddItem() { diff --git a/src/project.cpp b/src/project.cpp index 81f472ed..6ee18551 100644 --- a/src/project.cpp +++ b/src/project.cpp @@ -700,6 +700,34 @@ void Project::saveMapGroups() { mapGroupsFile.close(); } +void Project::saveMapSections() { + QString filepath = root + "/" + projectConfig.getFilePath(ProjectFilePath::constants_region_map_sections); + + QString text = QString("#ifndef GUARD_REGIONMAPSEC_H\n"); + text += QString("#define GUARD_REGIONMAPSEC_H\n\n"); + + int longestLength = 0; + for (QString label : this->mapSectionNameToValue.keys()) { + if (label.size() > longestLength) + longestLength = label.size(); + } + + // mapSectionValueToName + for (int value : this->mapSectionValueToName.keys()) { + QString line = QString("#define %1 0x%2\n") + .arg(this->mapSectionValueToName[value], -1 * longestLength) + .arg(QString("%1").arg(value, 2, 16, QLatin1Char('0')).toUpper()); + text += line; + } + + text += "\n" + this->extraFileText[projectConfig.getFilePath(ProjectFilePath::constants_region_map_sections)] + "\n"; + + text += QString("#endif // GUARD_REGIONMAPSEC_H\n"); + + ignoreWatchedFileTemporarily(filepath); + saveTextFile(filepath, text); +} + void Project::saveWildMonData() { if (!userConfig.getEncounterJsonActive()) return; @@ -1421,6 +1449,7 @@ void Project::updateLayout(Layout *layout) { void Project::saveAllDataStructures() { saveMapLayouts(); saveMapGroups(); + saveMapSections(); saveMapConstantsHeader(); saveWildMonData(); } @@ -2158,9 +2187,46 @@ bool Project::readRegionMapSections() { for (QString defineName : this->mapSectionNameToValue.keys()) { this->mapSectionValueToName.insert(this->mapSectionNameToValue[defineName], defineName); } + + // extra text + QString extraText; + QString fileText = ParseUtil::readTextFile(root + "/" + filename); + QTextStream stream(&fileText); + QString currentLine; + while (stream.readLineInto(¤tLine)) { + // is this line something that porymap will output again? + if (currentLine.isEmpty()) { + continue; + } + // include guards + else if (currentLine.contains("GUARD_REGIONMAPSEC_H")) { + continue; + } + // defines captured (not considering comments) + else if (currentLine.contains("#define " + projectConfig.getIdentifier(ProjectIdentifier::define_map_section_prefix))) { + continue; + } + // everything else should be kept here + else { + extraText += currentLine + "\n"; + } + } + stream.seek(0); + this->extraFileText[filename] = extraText; return true; } +int Project::appendMapsec(QString name) { + // This function assumes a valid and unique name. + // Will return the new index. + int noneBefore = this->mapSectionNameToValue[projectConfig.getIdentifier(ProjectIdentifier::define_map_section_prefix) + "NONE"]; + this->mapSectionNameToValue[name] = noneBefore; + this->mapSectionValueToName[noneBefore] = name; + this->mapSectionNameToValue[projectConfig.getIdentifier(ProjectIdentifier::define_map_section_prefix) + "NONE"] = noneBefore + 1; + this->mapSectionValueToName[noneBefore + 1] = projectConfig.getIdentifier(ProjectIdentifier::define_map_section_prefix) + "NONE"; + return noneBefore; +} + // Read the constants to preserve any "unused" heal locations when writing the file later bool Project::readHealLocationConstants() { this->healLocationNameToValue.clear(); diff --git a/src/ui/maplistmodels.cpp b/src/ui/maplistmodels.cpp index a572c7eb..8dbc24b8 100644 --- a/src/ui/maplistmodels.cpp +++ b/src/ui/maplistmodels.cpp @@ -392,6 +392,14 @@ QStandardItem *MapAreaModel::createMapItem(QString mapName, int groupIndex, int return map; } +QStandardItem *MapAreaModel::insertAreaItem(QString areaName) { + int newAreaIndex = this->project->appendMapsec(areaName); + QStandardItem *item = createAreaItem(areaName, newAreaIndex); + this->root->insertRow(newAreaIndex, item); + this->areaItems["MAPSEC_NONE"]->setData(newAreaIndex + 1, MapListRoles::GroupRole); + return item; +} + QStandardItem *MapAreaModel::insertMapItem(QString mapName, QString areaName, int groupIndex) { // int areaIndex = this->project->mapSectionNameToValue[areaName]; QStandardItem *area = this->areaItems[areaName];