Split project config
- Project config is now split into project and user config. - Backwards compatibility with the old project config included, porting old project items over to the new user config.
This commit is contained in:
parent
0fa71dc4c8
commit
8e83daac84
7 changed files with 147 additions and 62 deletions
|
@ -10,7 +10,11 @@ A global settings file is stored in a platform-dependent location for app config
|
|||
|
||||
A config file is also created when opening a project in porymap for the first time. It is stored in
|
||||
your project root as ``porymap.project.cfg``. There are several project-specific settings that are
|
||||
determined by this file.
|
||||
determined by this file. You may want to check in this file so that other users will have your
|
||||
porject settings.
|
||||
|
||||
A second config file is created for user-specific settings. It is stored in
|
||||
your project root as ``porymap.user.cfg``. You should add this file to your gitignore.
|
||||
|
||||
.. csv-table::
|
||||
:header: Setting,Default,Location,Can Edit?,Description
|
||||
|
@ -18,7 +22,7 @@ determined by this file.
|
|||
|
||||
``recent_project``, , global, yes, The project that will be opened on launch
|
||||
``reopen_on_launch``, 1, global, yes, Whether the most recent project should be opened on launch
|
||||
``recent_map``, , global, yes, The map that will be opened on launch
|
||||
``recent_map``, , user, yes, The map that will be opened on launch
|
||||
``pretty_cursors``, 1, global, yes, Whether to use custom crosshair cursors
|
||||
``map_sort_order``, group, global, yes, The order map list is sorted in
|
||||
``window_geometry``, , global, no, For restoring window sizes
|
||||
|
@ -35,7 +39,7 @@ determined by this file.
|
|||
``text_editor_goto_line``, , global, yes, The command that will be executed when clicking the button next the ``Script`` combo-box.
|
||||
``text_editor_open_directory``, , global, yes, The command that will be executed when clicking ``Open Project in Text Editor``.
|
||||
``base_game_version``, , project, no, The base pret repo for this project
|
||||
``use_encounter_json``, 1, project, yes, Enables wild encounter table editing
|
||||
``use_encounter_json``, 1, user, yes, Enables wild encounter table editing
|
||||
``use_poryscript``, 0, project, yes, Whether to open .pory files for scripts
|
||||
``use_custom_border_size``, 0, project, yes, Whether to allow variable border sizes
|
||||
``enable_event_weather_trigger``, 1 if not ``pokefirered``, project, yes, Allows adding Weather Trigger events
|
||||
|
@ -47,6 +51,6 @@ determined by this file.
|
|||
``enable_floor_number``, 1 if ``pokefirered``, project, yes, Adds ``Floor Number`` to map headers
|
||||
``create_map_text_file``, 1 if not ``pokeemerald``, project, yes, A ``text.inc`` or ``text.pory`` file will be created for any new map
|
||||
``enable_triple_layer_metatiles``, 0, project, yes, Enables triple-layer metatiles (See https://github.com/pret/pokeemerald/wiki/Triple-layer-metatiles)
|
||||
``custom_scripts``, , project, yes, A list of script files to load into the scripting engine
|
||||
``custom_scripts``, , user, yes, A list of script files to load into the scripting engine
|
||||
|
||||
Some of these settings can be toggled manually in porymap via the *Options* menu.
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
#include <QKeySequence>
|
||||
#include <QMultiMap>
|
||||
|
||||
#define CONFIG_BACKWARDS_COMPATABILITY
|
||||
|
||||
enum MapSortOrder {
|
||||
Group = 0,
|
||||
Area = 1,
|
||||
|
@ -145,8 +147,6 @@ public:
|
|||
}
|
||||
virtual void reset() override {
|
||||
this->baseGameVersion = BaseGameVersion::pokeemerald;
|
||||
this->recentMap = QString();
|
||||
this->useEncounterJson = true;
|
||||
this->useCustomBorderSize = false;
|
||||
this->enableEventWeatherTrigger = true;
|
||||
this->enableEventSecretBase = true;
|
||||
|
@ -157,16 +157,11 @@ public:
|
|||
this->enableFloorNumber = false;
|
||||
this->createMapTextFile = false;
|
||||
this->enableTripleLayerMetatiles = false;
|
||||
this->customScripts.clear();
|
||||
this->readKeys.clear();
|
||||
}
|
||||
void setBaseGameVersion(BaseGameVersion baseGameVersion);
|
||||
BaseGameVersion getBaseGameVersion();
|
||||
QString getBaseGameVersionString();
|
||||
void setRecentMap(const QString &map);
|
||||
QString getRecentMap();
|
||||
void setEncounterJsonActive(bool active);
|
||||
bool getEncounterJsonActive();
|
||||
void setUsePoryScript(bool usePoryScript);
|
||||
bool getUsePoryScript();
|
||||
void setProjectDir(QString projectDir);
|
||||
|
@ -191,8 +186,6 @@ public:
|
|||
bool getCreateMapTextFileEnabled();
|
||||
void setTripleLayerMetatilesEnabled(bool enable);
|
||||
bool getTripleLayerMetatilesEnabled();
|
||||
void setCustomScripts(QList<QString> scripts);
|
||||
QList<QString> getCustomScripts();
|
||||
protected:
|
||||
virtual QString getConfigFilepath() override;
|
||||
virtual void parseConfigKeyValue(QString key, QString value) override;
|
||||
|
@ -202,8 +195,6 @@ protected:
|
|||
private:
|
||||
BaseGameVersion baseGameVersion;
|
||||
QString projectDir;
|
||||
QString recentMap;
|
||||
bool useEncounterJson;
|
||||
bool usePoryScript;
|
||||
bool useCustomBorderSize;
|
||||
bool enableEventWeatherTrigger;
|
||||
|
@ -215,12 +206,50 @@ private:
|
|||
bool enableFloorNumber;
|
||||
bool createMapTextFile;
|
||||
bool enableTripleLayerMetatiles;
|
||||
QList<QString> customScripts;
|
||||
QStringList readKeys;
|
||||
};
|
||||
|
||||
extern ProjectConfig projectConfig;
|
||||
|
||||
class UserConfig: public KeyValueConfigBase
|
||||
{
|
||||
public:
|
||||
UserConfig() {
|
||||
reset();
|
||||
}
|
||||
virtual void reset() override {
|
||||
this->recentMap = QString();
|
||||
this->useEncounterJson = true;
|
||||
this->customScripts.clear();
|
||||
this->readKeys.clear();
|
||||
}
|
||||
void setRecentMap(const QString &map);
|
||||
QString getRecentMap();
|
||||
void setEncounterJsonActive(bool active);
|
||||
bool getEncounterJsonActive();
|
||||
void setProjectDir(QString projectDir);
|
||||
QString getProjectDir();
|
||||
void setCustomScripts(QList<QString> scripts);
|
||||
QList<QString> getCustomScripts();
|
||||
protected:
|
||||
virtual QString getConfigFilepath() override;
|
||||
virtual void parseConfigKeyValue(QString key, QString value) override;
|
||||
virtual QMap<QString, QString> getKeyValueMap() override;
|
||||
virtual void onNewConfigFileCreated() override;
|
||||
virtual void setUnreadKeys() override;
|
||||
#ifdef CONFIG_BACKWARDS_COMPATABILITY
|
||||
friend class ProjectConfig;
|
||||
#endif
|
||||
private:
|
||||
QString projectDir;
|
||||
QString recentMap;
|
||||
bool useEncounterJson;
|
||||
QList<QString> customScripts;
|
||||
QStringList readKeys;
|
||||
};
|
||||
|
||||
extern UserConfig userConfig;
|
||||
|
||||
class QAction;
|
||||
class Shortcut;
|
||||
|
||||
|
|
111
src/config.cpp
111
src/config.cpp
|
@ -468,10 +468,6 @@ void ProjectConfig::parseConfigKeyValue(QString key, QString value) {
|
|||
this->baseGameVersion = BaseGameVersion::pokeemerald;
|
||||
logWarn(QString("Invalid config value for base_game_version: '%1'. Must be 'pokeruby', 'pokefirered' or 'pokeemerald'.").arg(value));
|
||||
}
|
||||
} else if (key == "recent_map") {
|
||||
this->recentMap = value;
|
||||
} else if (key == "use_encounter_json") {
|
||||
setConfigBool(key, &this->useEncounterJson, value);
|
||||
} else if (key == "use_poryscript") {
|
||||
setConfigBool(key, &this->usePoryScript, value);
|
||||
} else if (key == "use_custom_border_size") {
|
||||
|
@ -494,15 +490,21 @@ void ProjectConfig::parseConfigKeyValue(QString key, QString value) {
|
|||
setConfigBool(key, &this->createMapTextFile, value);
|
||||
} else if (key == "enable_triple_layer_metatiles") {
|
||||
setConfigBool(key, &this->enableTripleLayerMetatiles, value);
|
||||
#ifdef CONFIG_BACKWARDS_COMPATABILITY
|
||||
} else if (key == "recent_map") {
|
||||
userConfig.setRecentMap(value);
|
||||
} else if (key == "use_encounter_json") {
|
||||
userConfig.setConfigBool(key, &userConfig.useEncounterJson, value);
|
||||
} else if (key == "custom_scripts") {
|
||||
this->customScripts.clear();
|
||||
userConfig.customScripts.clear();
|
||||
QList<QString> paths = value.split(",");
|
||||
paths.removeDuplicates();
|
||||
for (QString script : paths) {
|
||||
if (!script.isEmpty()) {
|
||||
this->customScripts.append(script);
|
||||
userConfig.customScripts.append(script);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
logWarn(QString("Invalid config key found in config file %1: '%2'").arg(this->getConfigFilepath()).arg(key));
|
||||
}
|
||||
|
@ -526,8 +528,6 @@ void ProjectConfig::setUnreadKeys() {
|
|||
QMap<QString, QString> ProjectConfig::getKeyValueMap() {
|
||||
QMap<QString, QString> map;
|
||||
map.insert("base_game_version", baseGameVersionMap.value(this->baseGameVersion));
|
||||
map.insert("recent_map", this->recentMap);
|
||||
map.insert("use_encounter_json", QString::number(this->useEncounterJson));
|
||||
map.insert("use_poryscript", QString::number(this->usePoryScript));
|
||||
map.insert("use_custom_border_size", QString::number(this->useCustomBorderSize));
|
||||
map.insert("enable_event_weather_trigger", QString::number(this->enableEventWeatherTrigger));
|
||||
|
@ -539,7 +539,6 @@ QMap<QString, QString> ProjectConfig::getKeyValueMap() {
|
|||
map.insert("enable_floor_number", QString::number(this->enableFloorNumber));
|
||||
map.insert("create_map_text_file", QString::number(this->createMapTextFile));
|
||||
map.insert("enable_triple_layer_metatiles", QString::number(this->enableTripleLayerMetatiles));
|
||||
map.insert("custom_scripts", this->customScripts.join(","));
|
||||
return map;
|
||||
}
|
||||
|
||||
|
@ -579,10 +578,8 @@ void ProjectConfig::onNewConfigFileCreated() {
|
|||
this->enableEventCloneObject = isPokefirered;
|
||||
this->enableFloorNumber = isPokefirered;
|
||||
this->createMapTextFile = (this->baseGameVersion != BaseGameVersion::pokeemerald);
|
||||
this->useEncounterJson = true;
|
||||
this->usePoryScript = false;
|
||||
this->enableTripleLayerMetatiles = false;
|
||||
this->customScripts.clear();
|
||||
}
|
||||
|
||||
void ProjectConfig::setProjectDir(QString projectDir) {
|
||||
|
@ -606,24 +603,6 @@ QString ProjectConfig::getBaseGameVersionString() {
|
|||
return baseGameVersionMap.value(this->baseGameVersion);
|
||||
}
|
||||
|
||||
void ProjectConfig::setRecentMap(const QString &map) {
|
||||
this->recentMap = map;
|
||||
this->save();
|
||||
}
|
||||
|
||||
QString ProjectConfig::getRecentMap() {
|
||||
return this->recentMap;
|
||||
}
|
||||
|
||||
void ProjectConfig::setEncounterJsonActive(bool active) {
|
||||
this->useEncounterJson = active;
|
||||
this->save();
|
||||
}
|
||||
|
||||
bool ProjectConfig::getEncounterJsonActive() {
|
||||
return this->useEncounterJson;
|
||||
}
|
||||
|
||||
void ProjectConfig::setUsePoryScript(bool usePoryScript) {
|
||||
this->usePoryScript = usePoryScript;
|
||||
this->save();
|
||||
|
@ -723,12 +702,82 @@ bool ProjectConfig::getTripleLayerMetatilesEnabled() {
|
|||
return this->enableTripleLayerMetatiles;
|
||||
}
|
||||
|
||||
void ProjectConfig::setCustomScripts(QList<QString> scripts) {
|
||||
UserConfig userConfig;
|
||||
|
||||
QString UserConfig::getConfigFilepath() {
|
||||
// porymap config file is in the same directory as porymap itself.
|
||||
return QDir(this->projectDir).filePath("porymap.user.cfg");
|
||||
}
|
||||
|
||||
void UserConfig::parseConfigKeyValue(QString key, QString value) {
|
||||
if (key == "recent_map") {
|
||||
this->recentMap = value;
|
||||
} else if (key == "use_encounter_json") {
|
||||
setConfigBool(key, &this->useEncounterJson, value);
|
||||
} else if (key == "custom_scripts") {
|
||||
this->customScripts.clear();
|
||||
QList<QString> paths = value.split(",");
|
||||
paths.removeDuplicates();
|
||||
for (QString script : paths) {
|
||||
if (!script.isEmpty()) {
|
||||
this->customScripts.append(script);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logWarn(QString("Invalid config key found in config file %1: '%2'").arg(this->getConfigFilepath()).arg(key));
|
||||
}
|
||||
readKeys.append(key);
|
||||
}
|
||||
|
||||
void UserConfig::setUnreadKeys() {
|
||||
}
|
||||
|
||||
QMap<QString, QString> UserConfig::getKeyValueMap() {
|
||||
QMap<QString, QString> map;
|
||||
map.insert("recent_map", this->recentMap);
|
||||
map.insert("use_encounter_json", QString::number(this->useEncounterJson));
|
||||
map.insert("custom_scripts", this->customScripts.join(","));
|
||||
return map;
|
||||
}
|
||||
|
||||
void UserConfig::onNewConfigFileCreated() {
|
||||
QString dirName = QDir(this->projectDir).dirName().toLower();
|
||||
this->useEncounterJson = true;
|
||||
this->customScripts.clear();
|
||||
}
|
||||
|
||||
void UserConfig::setProjectDir(QString projectDir) {
|
||||
this->projectDir = projectDir;
|
||||
}
|
||||
|
||||
QString UserConfig::getProjectDir() {
|
||||
return this->projectDir;
|
||||
}
|
||||
|
||||
void UserConfig::setRecentMap(const QString &map) {
|
||||
this->recentMap = map;
|
||||
this->save();
|
||||
}
|
||||
|
||||
QString UserConfig::getRecentMap() {
|
||||
return this->recentMap;
|
||||
}
|
||||
|
||||
void UserConfig::setEncounterJsonActive(bool active) {
|
||||
this->useEncounterJson = active;
|
||||
this->save();
|
||||
}
|
||||
|
||||
bool UserConfig::getEncounterJsonActive() {
|
||||
return this->useEncounterJson;
|
||||
}
|
||||
|
||||
void UserConfig::setCustomScripts(QList<QString> scripts) {
|
||||
this->customScripts = scripts;
|
||||
this->save();
|
||||
}
|
||||
|
||||
QList<QString> ProjectConfig::getCustomScripts() {
|
||||
QList<QString> UserConfig::getCustomScripts() {
|
||||
return this->customScripts;
|
||||
}
|
||||
|
||||
|
|
|
@ -357,7 +357,7 @@ void MainWindow::setWildEncountersUIEnabled(bool enabled) {
|
|||
void MainWindow::setProjectSpecificUIVisibility()
|
||||
{
|
||||
ui->actionUse_Poryscript->setChecked(projectConfig.getUsePoryScript());
|
||||
this->setWildEncountersUIEnabled(projectConfig.getEncounterJsonActive());
|
||||
this->setWildEncountersUIEnabled(userConfig.getEncounterJsonActive());
|
||||
|
||||
switch (projectConfig.getBaseGameVersion())
|
||||
{
|
||||
|
@ -509,6 +509,8 @@ bool MainWindow::openProject(QString dir) {
|
|||
this->statusBar()->showMessage(QString("Opening project %1").arg(nativeDir));
|
||||
|
||||
bool success = true;
|
||||
userConfig.setProjectDir(dir);
|
||||
userConfig.load();
|
||||
projectConfig.setProjectDir(dir);
|
||||
projectConfig.load();
|
||||
|
||||
|
@ -570,7 +572,7 @@ QString MainWindow::getDefaultMap() {
|
|||
if (editor && editor->project) {
|
||||
QList<QStringList> names = editor->project->groupedMapNames;
|
||||
if (!names.isEmpty()) {
|
||||
QString recentMap = projectConfig.getRecentMap();
|
||||
QString recentMap = userConfig.getRecentMap();
|
||||
if (!recentMap.isNull() && recentMap.length() > 0) {
|
||||
for (int i = 0; i < names.length(); i++) {
|
||||
if (names.value(i).contains(recentMap)) {
|
||||
|
@ -597,8 +599,8 @@ QString MainWindow::getExistingDirectory(QString dir) {
|
|||
void MainWindow::on_action_Open_Project_triggered()
|
||||
{
|
||||
QString recent = ".";
|
||||
if (!projectConfig.getRecentMap().isEmpty()) {
|
||||
recent = projectConfig.getRecentMap();
|
||||
if (!userConfig.getRecentMap().isEmpty()) {
|
||||
recent = userConfig.getRecentMap();
|
||||
}
|
||||
QString dir = getExistingDirectory(recent);
|
||||
if (!dir.isEmpty()) {
|
||||
|
@ -742,7 +744,7 @@ void MainWindow::openWarpMap(QString map_name, QString event_id, QString event_g
|
|||
}
|
||||
|
||||
void MainWindow::setRecentMap(QString mapName) {
|
||||
projectConfig.setRecentMap(mapName);
|
||||
userConfig.setRecentMap(mapName);
|
||||
}
|
||||
|
||||
void MainWindow::displayMapProperties() {
|
||||
|
@ -1707,7 +1709,7 @@ void MainWindow::on_mainTabBar_tabBarClicked(int index)
|
|||
editor->setEditingConnections();
|
||||
}
|
||||
if (index != 4) {
|
||||
if (projectConfig.getEncounterJsonActive())
|
||||
if (userConfig.getEncounterJsonActive())
|
||||
editor->saveEncounterTabData();
|
||||
}
|
||||
if (index != 1) {
|
||||
|
@ -1758,7 +1760,7 @@ void MainWindow::on_actionUse_Encounter_Json_triggered(bool checked)
|
|||
warning.setText("You must reload the project for this setting to take effect.");
|
||||
warning.setIcon(QMessageBox::Information);
|
||||
warning.exec();
|
||||
projectConfig.setEncounterJsonActive(checked);
|
||||
userConfig.setEncounterJsonActive(checked);
|
||||
}
|
||||
|
||||
void MainWindow::on_actionMonitor_Project_Files_triggered(bool checked)
|
||||
|
@ -3217,6 +3219,7 @@ void MainWindow::closeEvent(QCloseEvent *event) {
|
|||
}
|
||||
}
|
||||
projectConfig.save();
|
||||
userConfig.save();
|
||||
}
|
||||
|
||||
porymapConfig.setMainGeometry(
|
||||
|
|
|
@ -1052,7 +1052,7 @@ QString MainWindow::getBaseGameVersion() {
|
|||
}
|
||||
|
||||
QList<QString> MainWindow::getCustomScripts() {
|
||||
return projectConfig.getCustomScripts();
|
||||
return userConfig.getCustomScripts();
|
||||
}
|
||||
|
||||
int MainWindow::getMainTab() {
|
||||
|
@ -1065,7 +1065,7 @@ void MainWindow::setMainTab(int index) {
|
|||
if (!this->ui || !this->ui->mainTabBar || index < 0 || index >= this->ui->mainTabBar->count())
|
||||
return;
|
||||
// Can't select Wild Encounters tab if it's disabled
|
||||
if (index == 4 && !projectConfig.getEncounterJsonActive())
|
||||
if (index == 4 && !userConfig.getEncounterJsonActive())
|
||||
return;
|
||||
this->on_mainTabBar_tabBarClicked(index);
|
||||
}
|
||||
|
|
|
@ -727,7 +727,7 @@ void Project::saveMapGroups() {
|
|||
}
|
||||
|
||||
void Project::saveWildMonData() {
|
||||
if (!projectConfig.getEncounterJsonActive()) return;
|
||||
if (!userConfig.getEncounterJsonActive()) return;
|
||||
|
||||
QString wildEncountersJsonFilepath = QString("%1/src/data/wild_encounters.json").arg(root);
|
||||
QFile wildEncountersFile(wildEncountersJsonFilepath);
|
||||
|
@ -1716,7 +1716,7 @@ bool Project::readWildMonData() {
|
|||
wildMonFields.clear();
|
||||
wildMonData.clear();
|
||||
encounterGroupLabels.clear();
|
||||
if (!projectConfig.getEncounterJsonActive()) {
|
||||
if (!userConfig.getEncounterJsonActive()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1727,7 +1727,7 @@ bool Project::readWildMonData() {
|
|||
if (!parser.tryParseOrderedJsonFile(&wildMonObj, wildMonJsonFilepath)) {
|
||||
// Failing to read wild encounters data is not a critical error, just disable the
|
||||
// encounter editor and log a warning in case the user intended to have this data.
|
||||
projectConfig.setEncounterJsonActive(false);
|
||||
userConfig.setEncounterJsonActive(false);
|
||||
emit disableWildEncountersUI();
|
||||
logWarn(QString("Failed to read wild encounters from %1").arg(wildMonJsonFilepath));
|
||||
return true;
|
||||
|
@ -2295,7 +2295,7 @@ bool Project::readObjEventGfxConstants() {
|
|||
|
||||
bool Project::readMiscellaneousConstants() {
|
||||
miscConstants.clear();
|
||||
if (projectConfig.getEncounterJsonActive()) {
|
||||
if (userConfig.getEncounterJsonActive()) {
|
||||
QString filename = "include/constants/pokemon.h";
|
||||
fileWatcher.addPath(root + "/" + filename);
|
||||
QMap<QString, int> pokemonDefines = parser.readCDefines(filename, { "MIN_", "MAX_" });
|
||||
|
|
|
@ -30,7 +30,7 @@ Scripting::Scripting(MainWindow *mainWindow) {
|
|||
this->engine = new QJSEngine(mainWindow);
|
||||
this->engine->installExtensions(QJSEngine::ConsoleExtension);
|
||||
this->engine->globalObject().setProperty("map", this->engine->newQObject(mainWindow));
|
||||
for (QString script : projectConfig.getCustomScripts()) {
|
||||
for (QString script : userConfig.getCustomScripts()) {
|
||||
this->filepaths.append(script);
|
||||
}
|
||||
this->loadModules(this->filepaths);
|
||||
|
@ -40,7 +40,7 @@ void Scripting::loadModules(QStringList moduleFiles) {
|
|||
for (QString filepath : moduleFiles) {
|
||||
QJSValue module = this->engine->importModule(filepath);
|
||||
if (module.isError()) {
|
||||
QString relativePath = QDir::cleanPath(projectConfig.getProjectDir() + QDir::separator() + filepath);
|
||||
QString relativePath = QDir::cleanPath(userConfig.getProjectDir() + QDir::separator() + filepath);
|
||||
module = this->engine->importModule(relativePath);
|
||||
if (tryErrorJS(module)) continue;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue