From 143e5cf79be6b5cbad201fb5686e07b30f41b119 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Thu, 31 Aug 2023 13:47:13 -0400 Subject: [PATCH] Add button to import default prefabs --- forms/projectsettingseditor.ui | 34 +++++++------- include/config.h | 3 +- include/ui/prefab.h | 2 +- include/ui/projectsettingseditor.h | 1 + src/config.cpp | 14 ++++-- src/mainwindow.cpp | 7 ++- src/ui/prefab.cpp | 73 ++++++++++++++++++------------ src/ui/projectsettingseditor.cpp | 18 ++++++-- 8 files changed, 94 insertions(+), 58 deletions(-) diff --git a/forms/projectsettingseditor.ui b/forms/projectsettingseditor.ui index ed152444b..f2e86018f 100644 --- a/forms/projectsettingseditor.ui +++ b/forms/projectsettingseditor.ui @@ -29,7 +29,7 @@ 0 0 544 - 1096 + 1107 @@ -185,31 +185,31 @@ Prefabs - - - - - + + - Prefab import prompted + ... + + + + :/icons/folder.ico:/icons/folder.ico - - + + - Prefabs Path + Import Defaults - - + + + + + - ... - - - - :/icons/folder.ico:/icons/folder.ico + Prefabs Path diff --git a/include/config.h b/include/config.h index 86650d227..7ffcca38c 100644 --- a/include/config.h +++ b/include/config.h @@ -228,6 +228,7 @@ class ProjectConfig: public KeyValueConfigBase void setBaseGameVersion(BaseGameVersion baseGameVersion); BaseGameVersion getBaseGameVersion(); QString getBaseGameVersionString(); + QString getBaseGameVersionString(BaseGameVersion version); BaseGameVersion stringToBaseGameVersion(QString string, bool * ok = nullptr); void setUsePoryScript(bool usePoryScript); bool getUsePoryScript(); @@ -269,7 +270,7 @@ class ProjectConfig: public KeyValueConfigBase void setFilePath(ProjectFilePath pathId, QString path); QString getFilePath(ProjectFilePath pathId); void setPrefabFilepath(QString filepath); - QString getPrefabFilepath(bool setIfEmpty); + QString getPrefabFilepath(); void setPrefabImportPrompted(bool prompted); bool getPrefabImportPrompted(); void setTilesetsHaveCallback(bool has); diff --git a/include/ui/prefab.h b/include/ui/prefab.h index 00b2d7144..7bd9e0b24 100644 --- a/include/ui/prefab.h +++ b/include/ui/prefab.h @@ -23,7 +23,7 @@ class Prefab void initPrefabUI(MetatileSelector *selector, QWidget *prefabWidget, QLabel *emptyPrefabLabel, Map *map); void addPrefab(MetatileSelection selection, Map *map, QString name); void updatePrefabUi(Map *map); - void tryImportDefaultPrefabs(Map *map); + bool tryImportDefaultPrefabs(QWidget * parent, BaseGameVersion version, QString filepath = ""); private: MetatileSelector *selector; diff --git a/include/ui/projectsettingseditor.h b/include/ui/projectsettingseditor.h index 180fb3667..03b3d14d7 100644 --- a/include/ui/projectsettingseditor.h +++ b/include/ui/projectsettingseditor.h @@ -44,6 +44,7 @@ class ProjectSettingsEditor : public QMainWindow private slots: void dialogButtonClicked(QAbstractButton *button); void choosePrefabsFileClicked(bool); + void importDefaultPrefabsClicked(bool); void markEdited(); }; diff --git a/src/config.cpp b/src/config.cpp index 89fff4799..7541a8949 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -801,8 +801,15 @@ BaseGameVersion ProjectConfig::getBaseGameVersion() { return this->baseGameVersion; } +QString ProjectConfig::getBaseGameVersionString(BaseGameVersion version) { + if (!baseGameVersionMap.contains(version)) { + version = BaseGameVersion::pokeemerald; + } + return baseGameVersionMap.value(version); +} + QString ProjectConfig::getBaseGameVersionString() { - return baseGameVersionMap.value(this->baseGameVersion); + return this->getBaseGameVersionString(this->baseGameVersion); } void ProjectConfig::setUsePoryScript(bool usePoryScript) { @@ -970,10 +977,7 @@ void ProjectConfig::setPrefabFilepath(QString filepath) { this->save(); } -QString ProjectConfig::getPrefabFilepath(bool setIfEmpty) { - if (setIfEmpty && this->prefabFilepath.isEmpty()) { - this->setPrefabFilepath("prefabs.json"); - } +QString ProjectConfig::getPrefabFilepath() { return this->prefabFilepath; } diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 92186032d..71283bc6c 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1678,7 +1678,12 @@ void MainWindow::on_mapViewTab_tabBarClicked(int index) editor->setEditingCollision(); } else if (index == 2) { editor->setEditingMap(); - prefab.tryImportDefaultPrefabs(this->editor->map); + if (projectConfig.getPrefabFilepath().isEmpty() && !projectConfig.getPrefabImportPrompted()) { + // User hasn't set up prefabs and hasn't been prompted before. + // Ask if they'd like to import the default prefabs file. + if (prefab.tryImportDefaultPrefabs(this, projectConfig.getBaseGameVersion())) + prefab.updatePrefabUi(this->editor->map); + } } editor->setCursorRectVisible(false); } diff --git a/src/ui/prefab.cpp b/src/ui/prefab.cpp index 87bae5181..9ad154f25 100644 --- a/src/ui/prefab.cpp +++ b/src/ui/prefab.cpp @@ -19,9 +19,11 @@ using OrderedJson = poryjson::Json; using OrderedJsonDoc = poryjson::JsonDoc; +const QString defaultFilepath = "prefabs.json"; + void Prefab::loadPrefabs() { this->items.clear(); - QString filepath = projectConfig.getPrefabFilepath(false); + QString filepath = projectConfig.getPrefabFilepath(); if (filepath.isEmpty()) return; ParseUtil parser; @@ -85,8 +87,11 @@ void Prefab::loadPrefabs() { } void Prefab::savePrefabs() { - QString filepath = projectConfig.getPrefabFilepath(true); - if (filepath.isEmpty()) return; + QString filepath = projectConfig.getPrefabFilepath(); + if (filepath.isEmpty()) { + filepath = defaultFilepath; + projectConfig.setPrefabFilepath(filepath); + } QFileInfo info(filepath); if (info.isRelative()) { @@ -269,48 +274,58 @@ void Prefab::addPrefab(MetatileSelection selection, Map *map, QString name) { this->updatePrefabUi(map); } -void Prefab::tryImportDefaultPrefabs(Map *map) { - BaseGameVersion version = projectConfig.getBaseGameVersion(); +bool Prefab::tryImportDefaultPrefabs(QWidget * parent, BaseGameVersion version, QString filepath) { // Ensure we have default prefabs for the project's game version. if (version != BaseGameVersion::pokeruby && version != BaseGameVersion::pokeemerald && version != BaseGameVersion::pokefirered) - return; - - // Exit early if the user has already setup prefabs. - if (!projectConfig.getPrefabFilepath(false).isEmpty()) - return; + return false; + + if (filepath.isEmpty()) + filepath = defaultFilepath; + + // Get the absolute filepath for writing/warnings + QString absFilepath; + QFileInfo fileInfo(filepath); + if (fileInfo.suffix().isEmpty()) + filepath += ".json"; + if (fileInfo.isRelative()) { + absFilepath = QDir::cleanPath(projectConfig.getProjectDir() + QDir::separator() + filepath); + } else { + absFilepath = filepath; + } - // Exit early if the user has already gone through this import prompt before. - if (projectConfig.getPrefabImportPrompted()) - return; + // The warning message when importing defaults changes if there's a pre-existing file. + QString fileWarning; + if (!QFileInfo::exists(absFilepath)) { + fileWarning = QString("This will create a file called '%1'").arg(absFilepath); + } else { + fileWarning = QString("This will overwrite any existing prefabs in '%1'").arg(absFilepath); + } // Display a dialog box to the user, asking if the default prefabs should be imported // into their project. QMessageBox::StandardButton prompt = - QMessageBox::question(nullptr, + QMessageBox::question(parent, "Import Default Prefabs", - QString("Would you like to import the default prefabs for %1? This will create a file called 'prefabs.json' in your project directory.") - .arg(projectConfig.getBaseGameVersionString()), + QString("Would you like to import the default prefabs for %1? %2.") + .arg(projectConfig.getBaseGameVersionString(version)) + .arg(fileWarning), QMessageBox::Yes | QMessageBox::No); - if (prompt == QMessageBox::Yes) { + bool acceptedImport = (prompt == QMessageBox::Yes); + if (acceptedImport) { // Sets up the default prefabs.json filepath. - QString filepath = projectConfig.getPrefabFilepath(true); - - QFileInfo info(filepath); - if (info.isRelative()) { - filepath = QDir::cleanPath(projectConfig.getProjectDir() + QDir::separator() + filepath); - } - QFile prefabsFile(filepath); + projectConfig.setPrefabFilepath(filepath); + QFile prefabsFile(absFilepath); if (!prefabsFile.open(QIODevice::WriteOnly)) { projectConfig.setPrefabFilepath(QString()); - logError(QString("Error: Could not open %1 for writing").arg(filepath)); - QMessageBox messageBox; + logError(QString("Error: Could not open %1 for writing").arg(absFilepath)); + QMessageBox messageBox(parent); messageBox.setText("Failed to import default prefabs file!"); - messageBox.setInformativeText(QString("Could not open \"%1\" for writing").arg(filepath)); + messageBox.setInformativeText(QString("Could not open \"%1\" for writing").arg(absFilepath)); messageBox.setIcon(QMessageBox::Warning); messageBox.exec(); - return; + return false; } ParseUtil parser; @@ -330,10 +345,10 @@ void Prefab::tryImportDefaultPrefabs(Map *map) { prefabsFile.write(content.toUtf8()); prefabsFile.close(); this->loadPrefabs(); - this->updatePrefabUi(map); } projectConfig.setPrefabImportPrompted(true); + return acceptedImport; } Prefab prefab; diff --git a/src/ui/projectsettingseditor.cpp b/src/ui/projectsettingseditor.cpp index a492c9eb8..48428624a 100644 --- a/src/ui/projectsettingseditor.cpp +++ b/src/ui/projectsettingseditor.cpp @@ -2,6 +2,7 @@ #include "ui_projectsettingseditor.h" #include "config.h" #include "noscrollcombobox.h" +#include "prefab.h" #include #include @@ -31,8 +32,10 @@ ProjectSettingsEditor::~ProjectSettingsEditor() // TODO: Move tool tips to editable areas void ProjectSettingsEditor::connectSignals() { + // Connect buttons connect(ui->buttonBox, &QDialogButtonBox::clicked, this, &ProjectSettingsEditor::dialogButtonClicked); connect(ui->button_ChoosePrefabs, &QAbstractButton::clicked, this, &ProjectSettingsEditor::choosePrefabsFileClicked); + connect(ui->button_ImportDefaultPrefabs, &QAbstractButton::clicked, this, &ProjectSettingsEditor::importDefaultPrefabsClicked); // Connect combo boxes QList combos = ui->centralwidget->findChildren(); @@ -106,7 +109,6 @@ void ProjectSettingsEditor::refresh() { ui->checkBox_UsePoryscript->setChecked(projectConfig.getUsePoryScript()); ui->checkBox_ShowWildEncounterTables->setChecked(userConfig.getEncounterJsonActive()); ui->checkBox_CreateTextFile->setChecked(projectConfig.getCreateMapTextFileEnabled()); - ui->checkBox_PrefabImportPrompted->setChecked(projectConfig.getPrefabImportPrompted()); ui->checkBox_EnableTripleLayerMetatiles->setChecked(projectConfig.getTripleLayerMetatilesEnabled()); ui->checkBox_EnableRequiresItemfinder->setChecked(projectConfig.getHiddenItemRequiresItemfinderEnabled()); ui->checkBox_EnableQuantity->setChecked(projectConfig.getHiddenItemQuantityEnabled()); @@ -130,7 +132,7 @@ void ProjectSettingsEditor::refresh() { // Set line edit texts ui->lineEdit_BorderMetatiles->setText(projectConfig.getNewMapBorderMetatileIdsString()); - ui->lineEdit_PrefabsPath->setText(projectConfig.getPrefabFilepath(false)); + ui->lineEdit_PrefabsPath->setText(projectConfig.getPrefabFilepath()); this->refreshing = false; // Allow signals } @@ -150,7 +152,6 @@ void ProjectSettingsEditor::save() { projectConfig.setUsePoryScript(ui->checkBox_UsePoryscript->isChecked()); userConfig.setEncounterJsonActive(ui->checkBox_ShowWildEncounterTables->isChecked()); projectConfig.setCreateMapTextFileEnabled(ui->checkBox_CreateTextFile->isChecked()); - projectConfig.setPrefabImportPrompted(ui->checkBox_PrefabImportPrompted->isChecked()); projectConfig.setTripleLayerMetatilesEnabled(ui->checkBox_EnableTripleLayerMetatiles->isChecked()); projectConfig.setHiddenItemRequiresItemfinderEnabled(ui->checkBox_EnableRequiresItemfinder->isChecked()); projectConfig.setHiddenItemQuantityEnabled(ui->checkBox_EnableQuantity->isChecked()); @@ -203,10 +204,19 @@ void ProjectSettingsEditor::choosePrefabsFileClicked(bool) { return; this->project->setImportExportPath(filepath); ui->lineEdit_PrefabsPath->setText(filepath); - ui->checkBox_PrefabImportPrompted->setChecked(true); this->hasUnsavedChanges = true; } +void ProjectSettingsEditor::importDefaultPrefabsClicked(bool) { + // If the prompt is accepted the prefabs file will be created and its filepath will be saved in the config. + // No need to set hasUnsavedChanges here. + BaseGameVersion version = projectConfig.stringToBaseGameVersion(ui->comboBox_BaseGameVersion->currentText()); + if (prefab.tryImportDefaultPrefabs(this, version, ui->lineEdit_PrefabsPath->text())) { + ui->lineEdit_PrefabsPath->setText(projectConfig.getPrefabFilepath()); // Refresh with new filepath + this->projectNeedsReload = true; + } +} + int ProjectSettingsEditor::prompt(const QString &text, QMessageBox::StandardButton defaultButton) { QMessageBox messageBox(this); messageBox.setText(text);