porymap/src/config.cpp

874 lines
30 KiB
C++
Raw Normal View History

2018-12-21 15:25:28 +00:00
#include "config.h"
#include "log.h"
#include "shortcut.h"
2018-12-21 15:25:28 +00:00
#include <QDir>
#include <QFile>
#include <QFormLayout>
#include <QDialog>
#include <QDialogButtonBox>
2018-12-21 15:25:28 +00:00
#include <QList>
#include <QComboBox>
#include <QLabel>
2018-12-21 15:25:28 +00:00
#include <QTextStream>
#include <QRegularExpression>
#include <QStandardPaths>
#include <QAction>
#include <QAbstractButton>
2018-12-21 15:25:28 +00:00
KeyValueConfigBase::~KeyValueConfigBase() {
2018-12-21 15:25:28 +00:00
}
2018-12-21 15:25:28 +00:00
void KeyValueConfigBase::load() {
2020-04-07 19:44:14 +01:00
reset();
QFile file(this->getConfigFilepath());
2018-12-21 15:25:28 +00:00
if (!file.exists()) {
if (!file.open(QIODevice::WriteOnly)) {
logError(QString("Could not create config file '%1'").arg(this->getConfigFilepath()));
2018-12-21 15:25:28 +00:00
} else {
file.close();
this->onNewConfigFileCreated();
this->save();
2018-12-21 15:25:28 +00:00
}
}
if (!file.open(QIODevice::ReadOnly)) {
logError(QString("Could not open config file '%1': ").arg(this->getConfigFilepath()) + file.errorString());
2018-12-21 15:25:28 +00:00
}
QTextStream in(&file);
QList<QString> configLines;
2020-11-01 00:28:16 +00:00
QRegularExpression re("^(?<key>[^=]+)=(?<value>.*)$");
2018-12-21 15:25:28 +00:00
while (!in.atEnd()) {
QString line = in.readLine().trimmed();
int commentIndex = line.indexOf("#");
if (commentIndex >= 0) {
line = line.left(commentIndex).trimmed();
}
if (line.length() == 0) {
continue;
}
QRegularExpressionMatch match = re.match(line);
if (!match.hasMatch()) {
logWarn(QString("Invalid config line in %1: '%2'").arg(this->getConfigFilepath()).arg(line));
2018-12-21 15:25:28 +00:00
continue;
}
this->parseConfigKeyValue(match.captured("key").toLower(), match.captured("value"));
2018-12-21 15:25:28 +00:00
}
2020-05-26 22:01:18 +01:00
this->setUnreadKeys();
2018-12-21 15:25:28 +00:00
file.close();
}
void KeyValueConfigBase::save() {
QString text = "";
QMap<QString, QString> map = this->getKeyValueMap();
for (QMap<QString, QString>::iterator it = map.begin(); it != map.end(); it++) {
text += QString("%1=%2\n").arg(it.key()).arg(it.value());
}
QFile file(this->getConfigFilepath());
if (file.open(QIODevice::WriteOnly)) {
file.write(text.toUtf8());
file.close();
} else {
logError(QString("Could not open config file '%1' for writing: ").arg(this->getConfigFilepath()) + file.errorString());
}
}
2022-07-04 20:23:43 +01:00
void KeyValueConfigBase::setConfigBool(QString key, bool * field, QString value) {
bool ok;
*field = value.toInt(&ok);
if (!ok) {
logWarn(QString("Invalid config value for %1: '%2'. Must be 0 or 1.").arg(key).arg(value));
}
}
const QMap<MapSortOrder, QString> mapSortOrderMap = {
{MapSortOrder::Group, "group"},
{MapSortOrder::Layout, "layout"},
{MapSortOrder::Area, "area"},
};
const QMap<QString, MapSortOrder> mapSortOrderReverseMap = {
{"group", MapSortOrder::Group},
{"layout", MapSortOrder::Layout},
{"area", MapSortOrder::Area},
};
PorymapConfig porymapConfig;
QString PorymapConfig::getConfigFilepath() {
// porymap config file is in the same directory as porymap itself.
QString settingsPath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
QDir dir(settingsPath);
if (!dir.exists())
dir.mkpath(settingsPath);
QString configPath = dir.absoluteFilePath("porymap.cfg");
return configPath;
}
void PorymapConfig::parseConfigKeyValue(QString key, QString value) {
2018-12-21 15:25:28 +00:00
if (key == "recent_project") {
this->recentProject = value;
2022-07-04 20:47:03 +01:00
} else if (key == "reopen_on_launch") {
setConfigBool(key, &this->reopenOnLaunch, value);
2018-12-21 15:25:28 +00:00
} else if (key == "pretty_cursors") {
2022-07-04 20:23:43 +01:00
setConfigBool(key, &this->prettyCursors, value);
2018-12-21 15:25:28 +00:00
} else if (key == "map_sort_order") {
QString sortOrder = value.toLower();
if (mapSortOrderReverseMap.contains(sortOrder)) {
this->mapSortOrder = mapSortOrderReverseMap.value(sortOrder);
2018-12-21 15:25:28 +00:00
} else {
this->mapSortOrder = MapSortOrder::Group;
logWarn(QString("Invalid config value for map_sort_order: '%1'. Must be 'group', 'area', or 'layout'.").arg(value));
2018-12-21 15:25:28 +00:00
}
} else if (key == "main_window_geometry") {
this->mainWindowGeometry = bytesFromString(value);
} else if (key == "main_window_state") {
this->mainWindowState = bytesFromString(value);
} else if (key == "map_splitter_state") {
this->mapSplitterState = bytesFromString(value);
} else if (key == "main_splitter_state") {
this->mainSplitterState = bytesFromString(value);
} else if (key == "collision_opacity") {
bool ok;
this->collisionOpacity = qMax(0, qMin(100, value.toInt(&ok)));
if (!ok) {
logWarn(QString("Invalid config value for collision_opacity: '%1'. Must be an integer.").arg(value));
this->collisionOpacity = 50;
}
} else if (key == "tileset_editor_geometry") {
this->tilesetEditorGeometry = bytesFromString(value);
} else if (key == "tileset_editor_state") {
this->tilesetEditorState = bytesFromString(value);
} else if (key == "palette_editor_geometry") {
this->paletteEditorGeometry = bytesFromString(value);
} else if (key == "palette_editor_state") {
this->paletteEditorState = bytesFromString(value);
} else if (key == "region_map_editor_geometry") {
this->regionMapEditorGeometry = bytesFromString(value);
} else if (key == "region_map_editor_state") {
this->regionMapEditorState = bytesFromString(value);
2019-02-16 20:32:19 +00:00
} else if (key == "metatiles_zoom") {
bool ok;
this->metatilesZoom = qMax(10, qMin(100, value.toInt(&ok)));
if (!ok) {
logWarn(QString("Invalid config value for metatiles_zoom: '%1'. Must be an integer.").arg(value));
this->metatilesZoom = 30;
}
} else if (key == "show_player_view") {
2022-07-04 20:23:43 +01:00
setConfigBool(key, &this->showPlayerView, value);
} else if (key == "show_cursor_tile") {
2022-07-04 20:23:43 +01:00
setConfigBool(key, &this->showCursorTile, value);
} else if (key == "show_border") {
2022-07-04 20:23:43 +01:00
setConfigBool(key, &this->showBorder, value);
} else if (key == "show_grid") {
2022-07-04 20:23:43 +01:00
setConfigBool(key, &this->showGrid, value);
} else if (key == "monitor_files") {
2022-07-04 20:23:43 +01:00
setConfigBool(key, &this->monitorFiles, value);
} else if (key == "region_map_dimensions") {
bool ok1, ok2;
QStringList dims = value.split("x");
int w = dims[0].toInt(&ok1);
int h = dims[1].toInt(&ok2);
if (!ok1 || !ok2) {
logWarn("Cannot parse region map dimensions. Using default values instead.");
this->regionMapDimensions = QSize(32, 20);
} else {
this->regionMapDimensions = QSize(w, h);
}
} else if (key == "theme") {
this->theme = value;
} else if (key == "text_editor_open_directory") {
this->textEditorOpenFolder = value;
} else if (key == "text_editor_goto_line") {
this->textEditorGotoLine = value;
2018-12-21 15:25:28 +00:00
} else {
logWarn(QString("Invalid config key found in config file %1: '%2'").arg(this->getConfigFilepath()).arg(key));
2018-12-21 15:25:28 +00:00
}
}
QMap<QString, QString> PorymapConfig::getKeyValueMap() {
QMap<QString, QString> map;
map.insert("recent_project", this->recentProject);
2022-07-04 20:47:03 +01:00
map.insert("reopen_on_launch", this->reopenOnLaunch ? "1" : "0");
map.insert("pretty_cursors", this->prettyCursors ? "1" : "0");
map.insert("map_sort_order", mapSortOrderMap.value(this->mapSortOrder));
map.insert("main_window_geometry", stringFromByteArray(this->mainWindowGeometry));
map.insert("main_window_state", stringFromByteArray(this->mainWindowState));
map.insert("map_splitter_state", stringFromByteArray(this->mapSplitterState));
map.insert("main_splitter_state", stringFromByteArray(this->mainSplitterState));
map.insert("tileset_editor_geometry", stringFromByteArray(this->tilesetEditorGeometry));
map.insert("tileset_editor_state", stringFromByteArray(this->tilesetEditorState));
map.insert("palette_editor_geometry", stringFromByteArray(this->paletteEditorGeometry));
map.insert("palette_editor_state", stringFromByteArray(this->paletteEditorState));
map.insert("region_map_editor_geometry", stringFromByteArray(this->regionMapEditorGeometry));
map.insert("region_map_editor_state", stringFromByteArray(this->regionMapEditorState));
map.insert("collision_opacity", QString("%1").arg(this->collisionOpacity));
2019-02-16 20:32:19 +00:00
map.insert("metatiles_zoom", QString("%1").arg(this->metatilesZoom));
map.insert("show_player_view", this->showPlayerView ? "1" : "0");
map.insert("show_cursor_tile", this->showCursorTile ? "1" : "0");
map.insert("show_border", this->showBorder ? "1" : "0");
map.insert("show_grid", this->showGrid ? "1" : "0");
map.insert("monitor_files", this->monitorFiles ? "1" : "0");
map.insert("region_map_dimensions", QString("%1x%2").arg(this->regionMapDimensions.width())
.arg(this->regionMapDimensions.height()));
map.insert("theme", this->theme);
map.insert("text_editor_open_directory", this->textEditorOpenFolder);
map.insert("text_editor_goto_line", this->textEditorGotoLine);
return map;
2018-12-21 15:25:28 +00:00
}
QString PorymapConfig::stringFromByteArray(QByteArray bytearray) {
QString ret;
for (auto ch : bytearray) {
ret += QString::number(static_cast<int>(ch)) + ":";
}
return ret;
}
QByteArray PorymapConfig::bytesFromString(QString in) {
QByteArray ba;
QStringList split = in.split(":");
for (auto ch : split) {
ba.append(static_cast<char>(ch.toInt()));
}
return ba;
}
void PorymapConfig::setRecentProject(QString project) {
this->recentProject = project;
this->save();
2018-12-21 15:25:28 +00:00
}
2022-07-04 20:47:03 +01:00
void PorymapConfig::setReopenOnLaunch(bool enabled) {
this->reopenOnLaunch = enabled;
this->save();
}
void PorymapConfig::setMapSortOrder(MapSortOrder order) {
this->mapSortOrder = order;
this->save();
2018-12-21 15:25:28 +00:00
}
void PorymapConfig::setPrettyCursors(bool enabled) {
this->prettyCursors = enabled;
this->save();
2018-12-21 15:25:28 +00:00
}
void PorymapConfig::setMonitorFiles(bool monitor) {
this->monitorFiles = monitor;
this->save();
}
void PorymapConfig::setMainGeometry(QByteArray mainWindowGeometry_, QByteArray mainWindowState_,
QByteArray mapSplitterState_, QByteArray mainSplitterState_) {
this->mainWindowGeometry = mainWindowGeometry_;
this->mainWindowState = mainWindowState_;
this->mapSplitterState = mapSplitterState_;
this->mainSplitterState = mainSplitterState_;
this->save();
}
void PorymapConfig::setTilesetEditorGeometry(QByteArray tilesetEditorGeometry_, QByteArray tilesetEditorState_) {
this->tilesetEditorGeometry = tilesetEditorGeometry_;
this->tilesetEditorState = tilesetEditorState_;
this->save();
}
void PorymapConfig::setPaletteEditorGeometry(QByteArray paletteEditorGeometry_, QByteArray paletteEditorState_) {
this->paletteEditorGeometry = paletteEditorGeometry_;
this->paletteEditorState = paletteEditorState_;
this->save();
}
void PorymapConfig::setRegionMapEditorGeometry(QByteArray regionMapEditorGeometry_, QByteArray regionMapEditorState_) {
this->regionMapEditorGeometry = regionMapEditorGeometry_;
this->regionMapEditorState = regionMapEditorState_;
this->save();
}
void PorymapConfig::setCollisionOpacity(int opacity) {
this->collisionOpacity = opacity;
// don't auto-save here because this can be called very frequently.
}
2019-02-16 20:32:19 +00:00
void PorymapConfig::setMetatilesZoom(int zoom) {
this->metatilesZoom = zoom;
// don't auto-save here because this can be called very frequently.
}
void PorymapConfig::setShowPlayerView(bool enabled) {
this->showPlayerView = enabled;
this->save();
}
void PorymapConfig::setShowCursorTile(bool enabled) {
this->showCursorTile = enabled;
this->save();
}
void PorymapConfig::setShowBorder(bool enabled) {
this->showBorder = enabled;
this->save();
}
void PorymapConfig::setShowGrid(bool enabled) {
this->showGrid = enabled;
this->save();
}
void PorymapConfig::setRegionMapDimensions(int width, int height) {
this->regionMapDimensions = QSize(width, height);
}
void PorymapConfig::setTheme(QString theme) {
this->theme = theme;
}
void PorymapConfig::setTextEditorOpenFolder(const QString &command) {
this->textEditorOpenFolder = command;
this->save();
}
void PorymapConfig::setTextEditorGotoLine(const QString &command) {
this->textEditorGotoLine = command;
this->save();
}
QString PorymapConfig::getRecentProject() {
return this->recentProject;
2018-12-21 15:25:28 +00:00
}
2022-07-04 20:47:03 +01:00
bool PorymapConfig::getReopenOnLaunch() {
return this->reopenOnLaunch;
}
MapSortOrder PorymapConfig::getMapSortOrder() {
return this->mapSortOrder;
2018-12-21 15:25:28 +00:00
}
bool PorymapConfig::getPrettyCursors() {
return this->prettyCursors;
2018-12-21 15:25:28 +00:00
}
QMap<QString, QByteArray> PorymapConfig::getMainGeometry() {
QMap<QString, QByteArray> geometry;
geometry.insert("main_window_geometry", this->mainWindowGeometry);
geometry.insert("main_window_state", this->mainWindowState);
geometry.insert("map_splitter_state", this->mapSplitterState);
geometry.insert("main_splitter_state", this->mainSplitterState);
return geometry;
}
QMap<QString, QByteArray> PorymapConfig::getTilesetEditorGeometry() {
QMap<QString, QByteArray> geometry;
geometry.insert("tileset_editor_geometry", this->tilesetEditorGeometry);
geometry.insert("tileset_editor_state", this->tilesetEditorState);
return geometry;
}
QMap<QString, QByteArray> PorymapConfig::getPaletteEditorGeometry() {
QMap<QString, QByteArray> geometry;
geometry.insert("palette_editor_geometry", this->paletteEditorGeometry);
geometry.insert("palette_editor_state", this->paletteEditorState);
return geometry;
}
QMap<QString, QByteArray> PorymapConfig::getRegionMapEditorGeometry() {
QMap<QString, QByteArray> geometry;
geometry.insert("region_map_editor_geometry", this->regionMapEditorGeometry);
geometry.insert("region_map_editor_state", this->regionMapEditorState);
return geometry;
}
int PorymapConfig::getCollisionOpacity() {
return this->collisionOpacity;
}
2019-02-16 20:32:19 +00:00
int PorymapConfig::getMetatilesZoom() {
return this->metatilesZoom;
}
bool PorymapConfig::getShowPlayerView() {
return this->showPlayerView;
}
bool PorymapConfig::getShowCursorTile() {
return this->showCursorTile;
}
bool PorymapConfig::getShowBorder() {
return this->showBorder;
}
bool PorymapConfig::getShowGrid() {
return this->showGrid;
}
bool PorymapConfig::getMonitorFiles() {
return this->monitorFiles;
}
QSize PorymapConfig::getRegionMapDimensions() {
return this->regionMapDimensions;
}
QString PorymapConfig::getTheme() {
return this->theme;
}
QString PorymapConfig::getTextEditorOpenFolder() {
return this->textEditorOpenFolder;
}
QString PorymapConfig::getTextEditorGotoLine() {
return this->textEditorGotoLine;
}
const QMap<BaseGameVersion, QString> baseGameVersionMap = {
{BaseGameVersion::pokeruby, "pokeruby"},
{BaseGameVersion::pokefirered, "pokefirered"},
{BaseGameVersion::pokeemerald, "pokeemerald"},
};
const QMap<QString, BaseGameVersion> baseGameVersionReverseMap = {
{"pokeruby", BaseGameVersion::pokeruby},
{"pokefirered", BaseGameVersion::pokefirered},
{"pokeemerald", BaseGameVersion::pokeemerald},
};
ProjectConfig projectConfig;
QString ProjectConfig::getConfigFilepath() {
// porymap config file is in the same directory as porymap itself.
return QDir(this->projectDir).filePath("porymap.project.cfg");
}
void ProjectConfig::parseConfigKeyValue(QString key, QString value) {
if (key == "base_game_version") {
QString baseGameVersion = value.toLower();
if (baseGameVersionReverseMap.contains(baseGameVersion)) {
this->baseGameVersion = baseGameVersionReverseMap.value(baseGameVersion);
} else {
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;
2019-07-03 21:21:48 +01:00
} else if (key == "use_encounter_json") {
2022-07-04 20:23:43 +01:00
setConfigBool(key, &this->useEncounterJson, value);
} else if (key == "use_poryscript") {
2022-07-04 20:23:43 +01:00
setConfigBool(key, &this->usePoryScript, value);
} else if (key == "use_custom_border_size") {
2022-07-04 20:23:43 +01:00
setConfigBool(key, &this->useCustomBorderSize, value);
} else if (key == "enable_event_weather_trigger") {
2022-07-04 20:23:43 +01:00
setConfigBool(key, &this->enableEventWeatherTrigger, value);
} else if (key == "enable_event_secret_base") {
2022-07-04 20:23:43 +01:00
setConfigBool(key, &this->enableEventSecretBase, value);
} else if (key == "enable_hidden_item_quantity") {
2022-07-04 20:23:43 +01:00
setConfigBool(key, &this->enableHiddenItemQuantity, value);
} else if (key == "enable_hidden_item_requires_itemfinder") {
2022-07-04 20:23:43 +01:00
setConfigBool(key, &this->enableHiddenItemRequiresItemfinder, value);
} else if (key == "enable_heal_location_respawn_data") {
2022-07-04 20:23:43 +01:00
setConfigBool(key, &this->enableHealLocationRespawnData, value);
2022-02-06 02:31:54 +00:00
} else if (key == "enable_event_clone_object") {
2022-07-04 20:23:43 +01:00
setConfigBool(key, &this->enableEventCloneObject, value);
} else if (key == "enable_floor_number") {
2022-07-04 20:23:43 +01:00
setConfigBool(key, &this->enableFloorNumber, value);
} else if (key == "create_map_text_file") {
2022-07-04 20:23:43 +01:00
setConfigBool(key, &this->createMapTextFile, value);
} else if (key == "enable_triple_layer_metatiles") {
2022-07-04 20:23:43 +01:00
setConfigBool(key, &this->enableTripleLayerMetatiles, 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);
}
}
2022-09-06 02:51:31 +01:00
} else if (key == "prefabs_filepath") {
this->prefabFilepath = value;
} else {
logWarn(QString("Invalid config key found in config file %1: '%2'").arg(this->getConfigFilepath()).arg(key));
}
2020-05-26 22:01:18 +01:00
readKeys.append(key);
}
void ProjectConfig::setUnreadKeys() {
// Set game-version specific defaults for any config field that wasn't read
bool isPokefirered = this->baseGameVersion == BaseGameVersion::pokefirered;
if (!readKeys.contains("use_custom_border_size")) this->useCustomBorderSize = isPokefirered;
if (!readKeys.contains("enable_event_weather_trigger")) this->enableEventWeatherTrigger = !isPokefirered;
if (!readKeys.contains("enable_event_secret_base")) this->enableEventSecretBase = !isPokefirered;
if (!readKeys.contains("enable_hidden_item_quantity")) this->enableHiddenItemQuantity = isPokefirered;
if (!readKeys.contains("enable_hidden_item_requires_itemfinder")) this->enableHiddenItemRequiresItemfinder = isPokefirered;
if (!readKeys.contains("enable_heal_location_respawn_data")) this->enableHealLocationRespawnData = isPokefirered;
2022-02-06 02:31:54 +00:00
if (!readKeys.contains("enable_event_clone_object")) this->enableEventCloneObject = isPokefirered;
2020-05-26 22:01:18 +01:00
if (!readKeys.contains("enable_floor_number")) this->enableFloorNumber = isPokefirered;
if (!readKeys.contains("create_map_text_file")) this->createMapTextFile = (this->baseGameVersion != BaseGameVersion::pokeemerald);
}
QMap<QString, QString> ProjectConfig::getKeyValueMap() {
QMap<QString, QString> map;
map.insert("base_game_version", baseGameVersionMap.value(this->baseGameVersion));
map.insert("recent_map", this->recentMap);
2019-07-03 21:21:48 +01:00
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));
map.insert("enable_event_secret_base", QString::number(this->enableEventSecretBase));
map.insert("enable_hidden_item_quantity", QString::number(this->enableHiddenItemQuantity));
map.insert("enable_hidden_item_requires_itemfinder", QString::number(this->enableHiddenItemRequiresItemfinder));
map.insert("enable_heal_location_respawn_data", QString::number(this->enableHealLocationRespawnData));
2022-02-06 02:31:54 +00:00
map.insert("enable_event_clone_object", QString::number(this->enableEventCloneObject));
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(","));
2022-09-06 02:51:31 +01:00
map.insert("prefabs_filepath", this->prefabFilepath);
return map;
}
void ProjectConfig::onNewConfigFileCreated() {
QString dirName = QDir(this->projectDir).dirName().toLower();
if (baseGameVersionReverseMap.contains(dirName)) {
this->baseGameVersion = baseGameVersionReverseMap.value(dirName);
logInfo(QString("Auto-detected base_game_version as '%1'").arg(dirName));
} else {
QDialog dialog(nullptr, Qt::WindowTitleHint);
dialog.setWindowTitle("Project Configuration");
dialog.setWindowModality(Qt::NonModal);
QFormLayout form(&dialog);
QComboBox *baseGameVersionComboBox = new QComboBox();
baseGameVersionComboBox->addItem("pokeruby", BaseGameVersion::pokeruby);
baseGameVersionComboBox->addItem("pokefirered", BaseGameVersion::pokefirered);
baseGameVersionComboBox->addItem("pokeemerald", BaseGameVersion::pokeemerald);
form.addRow(new QLabel("Game Version"), baseGameVersionComboBox);
QDialogButtonBox buttonBox(QDialogButtonBox::Ok, Qt::Horizontal, &dialog);
2021-02-18 13:43:52 +00:00
QObject::connect(&buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept);
form.addRow(&buttonBox);
if (dialog.exec() == QDialog::Accepted) {
this->baseGameVersion = static_cast<BaseGameVersion>(baseGameVersionComboBox->currentData().toInt());
}
}
bool isPokefirered = this->baseGameVersion == BaseGameVersion::pokefirered;
this->useCustomBorderSize = isPokefirered;
this->enableEventWeatherTrigger = !isPokefirered;
this->enableEventSecretBase = !isPokefirered;
this->enableHiddenItemQuantity = isPokefirered;
this->enableHiddenItemRequiresItemfinder = isPokefirered;
this->enableHealLocationRespawnData = isPokefirered;
2022-02-06 02:31:54 +00:00
this->enableEventCloneObject = isPokefirered;
this->enableFloorNumber = isPokefirered;
this->createMapTextFile = (this->baseGameVersion != BaseGameVersion::pokeemerald);
2019-07-03 21:21:48 +01:00
this->useEncounterJson = true;
this->usePoryScript = false;
this->enableTripleLayerMetatiles = false;
this->customScripts.clear();
}
void ProjectConfig::setProjectDir(QString projectDir) {
this->projectDir = projectDir;
}
QString ProjectConfig::getProjectDir() {
return this->projectDir;
}
void ProjectConfig::setBaseGameVersion(BaseGameVersion baseGameVersion) {
this->baseGameVersion = baseGameVersion;
this->save();
}
BaseGameVersion ProjectConfig::getBaseGameVersion() {
return this->baseGameVersion;
}
2019-07-03 21:21:48 +01:00
2021-12-15 04:50:56 +00:00
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;
}
2019-07-03 21:21:48 +01:00
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();
}
bool ProjectConfig::getUsePoryScript() {
return this->usePoryScript;
}
void ProjectConfig::setUseCustomBorderSize(bool enable) {
this->useCustomBorderSize = enable;
this->save();
}
bool ProjectConfig::getUseCustomBorderSize() {
return this->useCustomBorderSize;
}
void ProjectConfig::setEventWeatherTriggerEnabled(bool enable) {
this->enableEventWeatherTrigger = enable;
this->save();
}
bool ProjectConfig::getEventWeatherTriggerEnabled() {
return this->enableEventWeatherTrigger;
}
void ProjectConfig::setEventSecretBaseEnabled(bool enable) {
this->enableEventSecretBase = enable;
this->save();
}
bool ProjectConfig::getEventSecretBaseEnabled() {
return this->enableEventSecretBase;
}
void ProjectConfig::setHiddenItemQuantityEnabled(bool enable) {
this->enableHiddenItemQuantity = enable;
this->save();
}
bool ProjectConfig::getHiddenItemQuantityEnabled() {
return this->enableHiddenItemQuantity;
}
void ProjectConfig::setHiddenItemRequiresItemfinderEnabled(bool enable) {
this->enableHiddenItemRequiresItemfinder = enable;
this->save();
}
bool ProjectConfig::getHiddenItemRequiresItemfinderEnabled() {
return this->enableHiddenItemRequiresItemfinder;
}
void ProjectConfig::setHealLocationRespawnDataEnabled(bool enable) {
this->enableHealLocationRespawnData = enable;
this->save();
}
bool ProjectConfig::getHealLocationRespawnDataEnabled() {
return this->enableHealLocationRespawnData;
}
2022-02-06 02:31:54 +00:00
void ProjectConfig::setEventCloneObjectEnabled(bool enable) {
this->enableEventCloneObject = enable;
this->save();
}
2022-02-06 02:31:54 +00:00
bool ProjectConfig::getEventCloneObjectEnabled() {
return this->enableEventCloneObject;
}
void ProjectConfig::setFloorNumberEnabled(bool enable) {
this->enableFloorNumber = enable;
this->save();
}
bool ProjectConfig::getFloorNumberEnabled() {
return this->enableFloorNumber;
}
void ProjectConfig::setCreateMapTextFileEnabled(bool enable) {
this->createMapTextFile = enable;
this->save();
}
bool ProjectConfig::getCreateMapTextFileEnabled() {
return this->createMapTextFile;
}
void ProjectConfig::setTripleLayerMetatilesEnabled(bool enable) {
this->enableTripleLayerMetatiles = enable;
this->save();
}
bool ProjectConfig::getTripleLayerMetatilesEnabled() {
return this->enableTripleLayerMetatiles;
}
void ProjectConfig::setCustomScripts(QList<QString> scripts) {
this->customScripts = scripts;
this->save();
}
QList<QString> ProjectConfig::getCustomScripts() {
return this->customScripts;
}
2022-09-06 02:51:31 +01:00
void ProjectConfig::setPrefabFilepath(QString filepath) {
this->prefabFilepath = filepath;
this->save();
}
QString ProjectConfig::getPrefabFilepath() {
2022-09-10 14:54:16 +01:00
if (this->prefabFilepath.isEmpty()) {
this->setPrefabFilepath("prefabs.json");
2022-09-10 14:54:16 +01:00
}
2022-09-06 02:51:31 +01:00
return this->prefabFilepath;
}
ShortcutsConfig shortcutsConfig;
QString ShortcutsConfig::getConfigFilepath() {
QString settingsPath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
QDir dir(settingsPath);
if (!dir.exists())
dir.mkpath(settingsPath);
QString configPath = dir.absoluteFilePath("porymap.shortcuts.cfg");
return configPath;
}
void ShortcutsConfig::parseConfigKeyValue(QString key, QString value) {
QStringList keySequences = value.split(' ');
for (auto keySequence : keySequences)
user_shortcuts.insert(key, keySequence);
}
QMap<QString, QString> ShortcutsConfig::getKeyValueMap() {
QMap<QString, QString> map;
for (auto cfg_key : user_shortcuts.uniqueKeys()) {
auto keySequences = user_shortcuts.values(cfg_key);
QStringList keySequenceStrings;
for (auto keySequence : keySequences)
keySequenceStrings.append(keySequence.toString());
map.insert(cfg_key, keySequenceStrings.join(' '));
}
return map;
}
void ShortcutsConfig::setDefaultShortcuts(const QObjectList &objects) {
storeShortcutsFromList(StoreType::Default, objects);
2020-11-05 11:32:31 +00:00
save();
}
QList<QKeySequence> ShortcutsConfig::defaultShortcuts(const QObject *object) const {
return default_shortcuts.values(cfgKey(object));
}
void ShortcutsConfig::setUserShortcuts(const QObjectList &objects) {
storeShortcutsFromList(StoreType::User, objects);
2020-11-05 11:32:31 +00:00
save();
}
void ShortcutsConfig::setUserShortcuts(const QMultiMap<const QObject *, QKeySequence> &objects_keySequences) {
for (auto *object : objects_keySequences.uniqueKeys())
if (!object->objectName().isEmpty() && !object->objectName().startsWith("_q_"))
storeShortcuts(StoreType::User, cfgKey(object), objects_keySequences.values(object));
2020-11-05 11:32:31 +00:00
save();
}
QList<QKeySequence> ShortcutsConfig::userShortcuts(const QObject *object) const {
return user_shortcuts.values(cfgKey(object));
2020-11-05 11:32:31 +00:00
}
void ShortcutsConfig::storeShortcutsFromList(StoreType storeType, const QObjectList &objects) {
for (const auto *object : objects)
if (!object->objectName().isEmpty() && !object->objectName().startsWith("_q_"))
storeShortcuts(storeType, cfgKey(object), currentShortcuts(object));
2020-11-05 11:32:31 +00:00
}
void ShortcutsConfig::storeShortcuts(
2020-11-05 11:32:31 +00:00
StoreType storeType,
const QString &cfgKey,
const QList<QKeySequence> &keySequences)
{
bool storeUser = (storeType == User) || !user_shortcuts.contains(cfgKey);
2020-11-05 11:32:31 +00:00
if (storeType == Default)
default_shortcuts.remove(cfgKey);
2020-11-05 11:32:31 +00:00
if (storeUser)
user_shortcuts.remove(cfgKey);
2020-11-05 11:32:31 +00:00
if (keySequences.isEmpty()) {
if (storeType == Default)
default_shortcuts.insert(cfgKey, QKeySequence());
2020-11-05 11:32:31 +00:00
if (storeUser)
user_shortcuts.insert(cfgKey, QKeySequence());
2020-11-05 11:32:31 +00:00
} else {
for (auto keySequence : keySequences) {
if (storeType == Default)
default_shortcuts.insert(cfgKey, keySequence);
2020-11-05 11:32:31 +00:00
if (storeUser)
user_shortcuts.insert(cfgKey, keySequence);
2020-11-05 11:32:31 +00:00
}
}
}
/* Creates a config key from the object's name prepended with the parent
* window's object name, and converts camelCase to snake_case. */
QString ShortcutsConfig::cfgKey(const QObject *object) const {
2020-11-05 11:32:31 +00:00
auto cfg_key = QString();
auto *parentWidget = static_cast<QWidget *>(object->parent());
if (parentWidget)
cfg_key = parentWidget->window()->objectName() + '_';
cfg_key += object->objectName();
QRegularExpression re("[A-Z]");
int i = cfg_key.indexOf(re, 1);
while (i != -1) {
if (cfg_key.at(i - 1) != '_')
cfg_key.insert(i++, '_');
i = cfg_key.indexOf(re, i + 1);
}
return cfg_key.toLower();
}
QList<QKeySequence> ShortcutsConfig::currentShortcuts(const QObject *object) const {
if (object->inherits("QAction")) {
const auto *action = qobject_cast<const QAction *>(object);
return action->shortcuts();
} else if (object->inherits("Shortcut")) {
const auto *shortcut = qobject_cast<const Shortcut *>(object);
return shortcut->keys();
} else if (object->inherits("QShortcut")) {
const auto *qshortcut = qobject_cast<const QShortcut *>(object);
return { qshortcut->key() };
} else if (object->property("shortcut").isValid()) {
return { object->property("shortcut").value<QKeySequence>() };
} else {
return { };
}
}