diff --git a/docsrc/manual/scripting-capabilities.rst b/docsrc/manual/scripting-capabilities.rst
index 7c5452b1..8673a4a6 100644
--- a/docsrc/manual/scripting-capabilities.rst
+++ b/docsrc/manual/scripting-capabilities.rst
@@ -2289,7 +2289,7 @@ All constants are accessible via the global ``constants`` object.
.. js:attribute:: constants.base_game_version
- The string value of the config setting ``base_game_version``. This will either be ``pokeruby``, ``pokefirered``, or ``pokeemerald``.
+ The string value of the config setting ``base_game_version``. This will either be ``pokeruby``, ``pokefirered``, ``pokeemerald``, or an empty string.
.. js:attribute:: constants.version.major
diff --git a/forms/newlayoutdialog.ui b/forms/newlayoutdialog.ui
index 980b5351..303e11a1 100644
--- a/forms/newlayoutdialog.ui
+++ b/forms/newlayoutdialog.ui
@@ -6,8 +6,8 @@
0
0
- 264
- 173
+ 387
+ 357
@@ -36,8 +36,8 @@
0
0
- 240
- 109
+ 363
+ 293
diff --git a/forms/newlayoutform.ui b/forms/newlayoutform.ui
index b3c0649b..86107fb6 100644
--- a/forms/newlayoutform.ui
+++ b/forms/newlayoutform.ui
@@ -2,6 +2,14 @@
NewLayoutForm
+
+
+ 0
+ 0
+ 196
+ 331
+
+
Form
@@ -168,6 +176,9 @@
QComboBox::InsertPolicy::NoInsert
+
+ QComboBox::SizeAdjustPolicy::AdjustToMinimumContentsLengthWithIcon
+
-
@@ -204,6 +215,9 @@
QComboBox::InsertPolicy::NoInsert
+
+ QComboBox::SizeAdjustPolicy::AdjustToMinimumContentsLengthWithIcon
+
-
diff --git a/forms/newmapdialog.ui b/forms/newmapdialog.ui
index ec8c2612..9479b6dd 100644
--- a/forms/newmapdialog.ui
+++ b/forms/newmapdialog.ui
@@ -6,8 +6,8 @@
0
0
- 559
- 614
+ 467
+ 428
@@ -39,8 +39,8 @@
0
0
- 535
- 550
+ 443
+ 364
@@ -129,6 +129,9 @@
QComboBox::InsertPolicy::NoInsert
+
+ QComboBox::SizeAdjustPolicy::AdjustToMinimumContentsLengthWithIcon
+
-
@@ -171,6 +174,9 @@
QComboBox::InsertPolicy::NoInsert
+
+ QComboBox::SizeAdjustPolicy::AdjustToMinimumContentsLengthWithIcon
+
-
diff --git a/include/config.h b/include/config.h
index 6a6618bd..75ca58d0 100644
--- a/include/config.h
+++ b/include/config.h
@@ -48,13 +48,7 @@ public:
{ };
virtual ~KeyValueConfigBase() {};
- // Writes the contents of the config to disk.
- // Returns true if saving was successful, false otherwise.
virtual bool save();
-
- // Loads the contents of the config from disk.
- // Returns true if saving was successful, false otherwise.
- // A successful load includes initializing an empty or non-existing file.
virtual bool load();
virtual QJsonObject toJson();
diff --git a/include/ui/eventfilters.h b/include/ui/eventfilters.h
index f14d9b3b..d39e8474 100644
--- a/include/ui/eventfilters.h
+++ b/include/ui/eventfilters.h
@@ -37,5 +37,5 @@ public:
bool eventFilter(QObject *obj, QEvent *event) override;
private:
bool m_loggingEnabled = true;
- QSet m_wasShown;
+ QSet m_shown;
};
diff --git a/include/ui/projectsettingseditor.h b/include/ui/projectsettingseditor.h
index f14e74cf..34eb4207 100644
--- a/include/ui/projectsettingseditor.h
+++ b/include/ui/projectsettingseditor.h
@@ -71,6 +71,7 @@ private:
void addNewGlobalConstant();
void addGlobalConstant(const QString &name, const QString &expression);
QMap getGlobalConstants();
+ BaseGame::Version getBaseGameVersion() const;
private slots:
void dialogButtonClicked(QAbstractButton *button);
diff --git a/src/config.cpp b/src/config.cpp
index 0321c7e2..e2515350 100644
--- a/src/config.cpp
+++ b/src/config.cpp
@@ -434,10 +434,8 @@ void ProjectConfig::setVersionSpecificDefaults(BaseGame::Version version) {
0x9B, // MB_SECRET_BASE_SPOT_BLUE_CAVE_OPEN
0x9D, // MB_SECRET_BASE_SPOT_TREE_RIGHT_OPEN
};
- if (this->baseGameVersion == BaseGame::Version::pokeruby) {
- this->mapAllowFlagsEnabled = false;
- }
}
+ this->mapAllowFlagsEnabled = (this->baseGameVersion != BaseGame::Version::pokeruby);
}
bool ProjectConfig::save() {
@@ -472,6 +470,7 @@ QJsonObject ProjectConfig::getDefaultJson() const {
return defaultConfig.toJson();
}
+// TODO: Replace with a new prompt that allows choosing either the defaults for each version, or customizing settings.
void ProjectConfig::initializeFromEmpty() {
const QString dirName = QDir(projectDir()).dirName();
BaseGame::Version version = BaseGame::stringToVersion(dirName);
@@ -485,21 +484,18 @@ void ProjectConfig::initializeFromEmpty() {
QFormLayout form(&dialog);
- QComboBox *baseGameVersionComboBox = new QComboBox();
- // TODO: Populate dynamically, same as project settings editor
- baseGameVersionComboBox->addItem("pokeruby", BaseGame::Version::pokeruby);
- baseGameVersionComboBox->addItem("pokefirered", BaseGame::Version::pokefirered);
- baseGameVersionComboBox->addItem("pokeemerald", BaseGame::Version::pokeemerald);
- form.addRow(new QLabel("Game Version"), baseGameVersionComboBox);
-
- // TODO: Add an 'Advanced' button to open the project settings window (with some settings disabled)
+ auto comboBox = new QComboBox();
+ comboBox->addItem(BaseGame::versionToString(BaseGame::Version::pokeruby), BaseGame::Version::pokeruby);
+ comboBox->addItem(BaseGame::versionToString(BaseGame::Version::pokefirered), BaseGame::Version::pokefirered);
+ comboBox->addItem(BaseGame::versionToString(BaseGame::Version::pokeemerald), BaseGame::Version::pokeemerald);
+ form.addRow(new QLabel("Game Version"), comboBox);
QDialogButtonBox buttonBox(QDialogButtonBox::Ok, Qt::Horizontal, &dialog);
QObject::connect(&buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept);
form.addRow(&buttonBox);
if (dialog.exec() == QDialog::Accepted) {
- this->baseGameVersion = static_cast(baseGameVersionComboBox->currentData().toInt());
+ this->baseGameVersion = static_cast(comboBox->currentData().toInt());
} else {
logWarn(QString("No base_game_version selected, using default '%1'").arg(BaseGame::versionToString(this->baseGameVersion)));
}
diff --git a/src/config/legacy.cpp b/src/config/legacy.cpp
index e28776de..1407cc26 100644
--- a/src/config/legacy.cpp
+++ b/src/config/legacy.cpp
@@ -156,9 +156,9 @@ bool PorymapConfig::parseLegacyKeyValue(const QString &key, const QString &value
} else if (key == "text_editor_goto_line") {
this->textEditorGotoLine = value;
} else if (key == "palette_editor_bit_depth") {
- this->paletteEditorBitDepth = toInt(value, 15, 24, 24);
- if (this->paletteEditorBitDepth != 15 && this->paletteEditorBitDepth != 24){
- this->paletteEditorBitDepth = 24;
+ int bitDepth = toInt(value, 15, 24, 24);
+ if (bitDepth == 15 || bitDepth == 24){
+ this->paletteEditorBitDepth = bitDepth;
}
} else if (key == "project_settings_tab") {
this->projectSettingsTab = toInt(value, 0);
@@ -180,9 +180,7 @@ bool PorymapConfig::parseLegacyKeyValue(const QString &key, const QString &value
this->lastUpdateCheckTime = QDateTime::fromString(value).toLocalTime();
} else if (key == "last_update_check_version") {
auto version = QVersionNumber::fromString(value);
- if (version.segmentCount() != 3) {
- this->lastUpdateCheckVersion = porymapVersion;
- } else {
+ if (version.segmentCount() == 3) {
this->lastUpdateCheckVersion = version;
}
} else if (key.startsWith("rate_limit_time/")) {
diff --git a/src/core/basegame.cpp b/src/core/basegame.cpp
index 0646a357..0eecb123 100644
--- a/src/core/basegame.cpp
+++ b/src/core/basegame.cpp
@@ -13,14 +13,14 @@ BaseGame::Version BaseGame::stringToVersion(const QString &input_) {
};
const QString input(input_.toLower());
- BaseGame::Version version = BaseGame::Version::none;
+ Version version = Version::none;
for (auto it = versionDetectNames.begin(); it != versionDetectNames.end(); it++) {
// Compare the given string to all the possible names for this game version
for (const auto &name : it.value()) {
if (input.contains(name)) {
- if (version != BaseGame::Version::none) {
+ if (version != Version::none) {
// The given string matches multiple versions, so we can't be sure which it is.
- return BaseGame::Version::none;
+ return Version::none;
}
version = it.key();
break;
@@ -31,7 +31,6 @@ BaseGame::Version BaseGame::stringToVersion(const QString &input_) {
return version;
}
-// TODO: Make sure empty string is ok everywhere this is used
QString BaseGame::versionToString(BaseGame::Version version) {
static const QMap map = {
{Version::pokeruby, "pokeruby"},
@@ -42,15 +41,15 @@ QString BaseGame::versionToString(BaseGame::Version version) {
}
QString BaseGame::getPlayerIconPath(BaseGame::Version version, int character) {
- if (version == BaseGame::Version::pokeemerald) {
+ if (version == Version::pokeemerald) {
static const QStringList paths = { QStringLiteral(":/icons/player/brendan_em.ico"),
QStringLiteral(":/icons/player/may_em.ico"), };
return paths.value(character);
- } else if (version == BaseGame::Version::pokefirered) {
+ } else if (version == Version::pokefirered) {
static const QStringList paths = { QStringLiteral(":/icons/player/red.ico"),
QStringLiteral(":/icons/player/green.ico"), };
return paths.value(character);
- } else if (version == BaseGame::Version::pokeruby) {
+ } else if (version == Version::pokeruby) {
static const QStringList paths = { QStringLiteral(":/icons/player/brendan_rs.ico"),
QStringLiteral(":/icons/player/may_rs.ico"), };
return paths.value(character);
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 6d6056e9..b1b721a5 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -895,7 +895,8 @@ bool MainWindow::checkProjectVersion(Project *project) {
logInfo(QString("Successfully checked project version. Supports at least Porymap v%1").arg(minimumVersion.toString()));
}
if (minimumVersion > porymapVersion || minimumVersion.majorVersion() != porymapVersion.majorVersion()) {
- // We were unable to find the necessary changes for Porymap's current major version.
+ // Porymap is incompatible with the project if its version is below the specified minimum version,
+ // or if Porymap is so new that it exceeds the major version of the specified minimum version.
// Unless they have explicitly suppressed this message, warn the user that this might mean their project is missing breaking changes.
// Note: Do not report 'minimumVersion' to the user in this message. We've already logged it for troubleshooting.
// It is very plausible that the user may have reproduced the required changes in an
diff --git a/src/ui/eventfilters.cpp b/src/ui/eventfilters.cpp
index df3e65c4..d32c5b01 100644
--- a/src/ui/eventfilters.cpp
+++ b/src/ui/eventfilters.cpp
@@ -40,14 +40,15 @@ bool GeometrySaver::eventFilter(QObject *object, QEvent *event) {
if (m_loggingEnabled && !w->windowTitle().isEmpty()) {
logInfo(QString("Opening window: %1").arg(w->windowTitle()));
}
- m_wasShown.insert(object);
- } else if (event->type() == QEvent::Close && m_wasShown.contains(object)) {
+ m_shown.insert(object);
+ } else if (event->type() == QEvent::Close || event->type() == QEvent::DeferredDelete) {
// There are situations where a window might be 'closed' without
// ever actually having been opened (for example, the Shortcuts Editor
// will quietly construct windows to get their shortcuts, and those windows
// can later be closed without having been displayed).
// We don't want to save the geometry of these windows, or log that they closed,
- // so we've checked to make sure the widget was displayed before proceeding.
+ // so we checked to make sure the widget was displayed before proceeding.
+ if (!m_shown.remove(object)) return false;
porymapConfig.saveGeometry(w);
if (m_loggingEnabled && !w->windowTitle().isEmpty()) {
logInfo(QString("Closing window: %1").arg(w->windowTitle()));
diff --git a/src/ui/newlayoutdialog.cpp b/src/ui/newlayoutdialog.cpp
index c12ba566..16a82645 100644
--- a/src/ui/newlayoutdialog.cpp
+++ b/src/ui/newlayoutdialog.cpp
@@ -3,6 +3,7 @@
#include "ui_newlayoutdialog.h"
#include "config.h"
#include "validator.h"
+#include "eventfilters.h"
#include
#include
@@ -40,17 +41,12 @@ NewLayoutDialog::NewLayoutDialog(Project *project, const Layout *layoutToCopy, Q
connect(ui->buttonBox, &QDialogButtonBox::clicked, this, &NewLayoutDialog::dialogButtonClicked);
refresh();
-
- if (!porymapConfig.restoreGeometry(this)) {
- // On first display resize to fit contents a little better
- adjustSize();
- }
+ installEventFilter(new GeometrySaver(this));
ui->lineEdit_Name->setFocus();
}
NewLayoutDialog::~NewLayoutDialog()
{
- porymapConfig.saveGeometry(this);
saveSettings();
delete ui;
}
diff --git a/src/ui/projectsettingseditor.cpp b/src/ui/projectsettingseditor.cpp
index 5afcf81d..714ad326 100644
--- a/src/ui/projectsettingseditor.cpp
+++ b/src/ui/projectsettingseditor.cpp
@@ -111,12 +111,10 @@ void ProjectSettingsEditor::initUi() {
ui->comboBox_IconSpecies->addItems(project->speciesNames);
ui->comboBox_WarpBehaviors->addItems(project->metatileBehaviorMap.keys());
}
- // TODO: We don't need to keep converting these to/from strings, just include the value as data.
- ui->comboBox_BaseGameVersion->addItems({
- BaseGame::versionToString(BaseGame::Version::pokeruby),
- BaseGame::versionToString(BaseGame::Version::pokefirered),
- BaseGame::versionToString(BaseGame::Version::pokeemerald),
- });
+ ui->comboBox_BaseGameVersion->addItem("Custom", BaseGame::Version::none);
+ ui->comboBox_BaseGameVersion->addItem(BaseGame::versionToString(BaseGame::Version::pokeruby), BaseGame::Version::pokeruby);
+ ui->comboBox_BaseGameVersion->addItem(BaseGame::versionToString(BaseGame::Version::pokefirered), BaseGame::Version::pokefirered);
+ ui->comboBox_BaseGameVersion->addItem(BaseGame::versionToString(BaseGame::Version::pokeemerald), BaseGame::Version::pokeemerald);
ui->comboBox_AttributesSize->addItems({"1", "2", "4"});
ui->comboBox_EventsTabIcon->addItem("Automatic", "");
@@ -207,6 +205,10 @@ bool ProjectSettingsEditor::disableParsedSetting(QWidget * widget, const QString
return false;
}
+BaseGame::Version ProjectSettingsEditor::getBaseGameVersion() const {
+ return static_cast(ui->comboBox_BaseGameVersion->currentData().toInt());
+}
+
// Remember the current settings tab for future sessions
void ProjectSettingsEditor::on_mainTabs_tabBarClicked(int index) {
porymapConfig.projectSettingsTab = index;
@@ -447,7 +449,7 @@ void ProjectSettingsEditor::refresh() {
// Set combo box texts
ui->comboBox_DefaultPrimaryTileset->setTextItem(projectConfig.defaultPrimaryTileset);
ui->comboBox_DefaultSecondaryTileset->setTextItem(projectConfig.defaultSecondaryTileset);
- ui->comboBox_BaseGameVersion->setTextItem(BaseGame::versionToString(projectConfig.baseGameVersion));
+ ui->comboBox_BaseGameVersion->setNumberItem(projectConfig.baseGameVersion);
ui->comboBox_AttributesSize->setTextItem(QString::number(projectConfig.metatileAttributesSize));
this->updateAttributeLimits(ui->comboBox_AttributesSize->currentText());
@@ -555,7 +557,7 @@ void ProjectSettingsEditor::save() {
// Save combo box settings
projectConfig.defaultPrimaryTileset = ui->comboBox_DefaultPrimaryTileset->currentText();
projectConfig.defaultSecondaryTileset = ui->comboBox_DefaultSecondaryTileset->currentText();
- projectConfig.baseGameVersion = BaseGame::stringToVersion(ui->comboBox_BaseGameVersion->currentText());
+ projectConfig.baseGameVersion = getBaseGameVersion();
projectConfig.metatileAttributesSize = ui->comboBox_AttributesSize->currentText().toInt();
// Save check box settings
@@ -772,7 +774,7 @@ QString ProjectSettingsEditor::stripProjectDir(QString s) {
void ProjectSettingsEditor::importDefaultPrefabsClicked(bool) {
// If the prompt is accepted the prefabs file will be created and its filepath will be saved in the config.
- BaseGame::Version version = BaseGame::stringToVersion(ui->comboBox_BaseGameVersion->currentText());
+ BaseGame::Version version = getBaseGameVersion();
if (prefab.tryImportDefaultPrefabs(this, version, ui->lineEdit_PrefabsPath->text())) {
ui->lineEdit_PrefabsPath->setText(userConfig.prefabsFilepath); // Refresh with new filepath
this->hasUnsavedChanges = true;
@@ -804,19 +806,20 @@ bool ProjectSettingsEditor::promptSaveChanges() {
return true;
}
+// TODO: Changing the base game version implicitly changes defaults.
+// If the user declines this prompt, it should revert to the previous setting.
bool ProjectSettingsEditor::promptRestoreDefaults() {
if (this->refreshing)
return false;
- const QString versionText = ui->comboBox_BaseGameVersion->currentText();
- if (this->prompt(QString("Restore default config settings for %1?").arg(versionText)) == QMessageBox::No)
+ if (this->prompt(QString("Restore default config settings for %1?").arg(ui->comboBox_BaseGameVersion->currentText())) == QMessageBox::No)
return false;
// Restore defaults by resetting config in memory, refreshing the UI, then restoring the config.
// Don't want to save changes until user accepts them.
// TODO: Maybe give the project settings editor it's own copy of the config then.
ProjectConfig tempProject = projectConfig;
- projectConfig.setVersionSpecificDefaults(BaseGame::stringToVersion(versionText));
+ projectConfig.setVersionSpecificDefaults(getBaseGameVersion());
this->refresh();
projectConfig = tempProject;
diff --git a/src/ui/regionmapeditor.cpp b/src/ui/regionmapeditor.cpp
index ce0fa0ce..5f4cded0 100644
--- a/src/ui/regionmapeditor.cpp
+++ b/src/ui/regionmapeditor.cpp
@@ -115,42 +115,15 @@ bool RegionMapEditor::saveRegionMapEntries() {
return true;
}
-void buildEmeraldDefaults(poryjson::Json &json) {
- ParseUtil parser;
- QString emeraldDefault = parser.readTextFile(":/text/region_map_default_emerald.json");
- json = poryjson::Json::parse(emeraldDefault);
-}
-
-void buildRubyDefaults(poryjson::Json &json) {
- ParseUtil parser;
- QString emeraldDefault = parser.readTextFile(":/text/region_map_default_ruby.json");
- json = poryjson::Json::parse(emeraldDefault);
-}
-
-void buildFireredDefaults(poryjson::Json &json) {
-
- ParseUtil parser;
- QString fireredDefault = parser.readTextFile(":/text/region_map_default_firered.json");
- json = poryjson::Json::parse(fireredDefault);
-}
-
poryjson::Json RegionMapEditor::buildDefaultJson() {
- poryjson::Json defaultJson;
- switch (projectConfig.baseGameVersion) {
- case BaseGame::Version::pokeemerald:
- buildEmeraldDefaults(defaultJson);
- break;
- case BaseGame::Version::pokeruby:
- buildRubyDefaults(defaultJson);
- break;
- case BaseGame::Version::pokefirered:
- buildFireredDefaults(defaultJson);
- break;
- default:
- break;
- }
-
- return defaultJson;
+ static const QMap versionToJsonPath = {
+ {BaseGame::Version::pokeemerald, QStringLiteral(":/text/region_map_default_emerald.json")},
+ {BaseGame::Version::pokeruby, QStringLiteral(":/text/region_map_default_ruby.json")},
+ {BaseGame::Version::pokefirered, QStringLiteral(":/text/region_map_default_firered.json")},
+ };
+ const QString path = versionToJsonPath.value(projectConfig.baseGameVersion);
+ if (path.isEmpty()) { Q_ASSERT(false); return OrderedJson::object(); }
+ return OrderedJson::parse(ParseUtil::readTextFile(path));
}
bool RegionMapEditor::buildConfigDialog() {
@@ -276,6 +249,8 @@ bool RegionMapEditor::buildConfigDialog() {
// for sake of convenience, option to just use defaults for each basegame version
+ // TODO: Each version's default settings should be available regardless of the base game version,
+ // it can just suggest which default settings to use depending on the base game version.
QPushButton *config_useProjectDefault = nullptr;
switch (projectConfig.baseGameVersion) {
case BaseGame::Version::pokefirered:
@@ -288,6 +263,8 @@ bool RegionMapEditor::buildConfigDialog() {
config_useProjectDefault = new QPushButton("\nUse pokeruby defaults\n");
break;
default:
+ config_useProjectDefault = new QPushButton("\nNo default settings available\n");
+ config_useProjectDefault->setEnabled(false);
break;
}
form.addRow(config_useProjectDefault);