Merge pull request #734 from GriffinRichards/config-file

Fix some issues with config loading
This commit is contained in:
GriffinR 2025-05-22 14:28:13 -04:00 committed by GitHub
commit 947142e370
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 79 additions and 86 deletions

View File

@ -29,11 +29,21 @@ class KeyValueConfigBase
{ {
public: public:
bool save(); bool save();
void load(); bool load(const QString &dir = QString());
virtual ~KeyValueConfigBase();
void setRoot(const QString &dir);
QString root() const { return m_root; }
QString filepath() const { return m_filepath; }
QString filename() const { return m_filename; }
explicit KeyValueConfigBase(const QString &filename)
: m_root(QString()),
m_filename(filename),
m_filepath(filename)
{ };
virtual ~KeyValueConfigBase() {};
virtual void reset() = 0; virtual void reset() = 0;
protected: protected:
virtual QString getConfigFilepath() = 0;
virtual void parseConfigKeyValue(QString key, QString value) = 0; virtual void parseConfigKeyValue(QString key, QString value) = 0;
virtual QMap<QString, QString> getKeyValueMap() = 0; virtual QMap<QString, QString> getKeyValueMap() = 0;
virtual void init() = 0; virtual void init() = 0;
@ -43,14 +53,16 @@ protected:
static int getConfigInteger(const QString &key, const QString &value, int min = INT_MIN, int max = INT_MAX, int defaultValue = 0); static int getConfigInteger(const QString &key, const QString &value, int min = INT_MIN, int max = INT_MAX, int defaultValue = 0);
static uint32_t getConfigUint32(const QString &key, const QString &value, uint32_t min = 0, uint32_t max = UINT_MAX, uint32_t defaultValue = 0); static uint32_t getConfigUint32(const QString &key, const QString &value, uint32_t min = 0, uint32_t max = UINT_MAX, uint32_t defaultValue = 0);
static QColor getConfigColor(const QString &key, const QString &value, const QColor &defaultValue = Qt::black); static QColor getConfigColor(const QString &key, const QString &value, const QColor &defaultValue = Qt::black);
QString m_root;
QString m_filename;
QString m_filepath;
}; };
class PorymapConfig: public KeyValueConfigBase class PorymapConfig: public KeyValueConfigBase
{ {
public: public:
PorymapConfig() { PorymapConfig();
reset();
}
virtual void reset() override { virtual void reset() override {
this->recentProjects.clear(); this->recentProjects.clear();
this->projectManuallyClosed = false; this->projectManuallyClosed = false;
@ -167,7 +179,6 @@ public:
std::set<LogType> statusBarLogTypes; std::set<LogType> statusBarLogTypes;
protected: protected:
virtual QString getConfigFilepath() override;
virtual void parseConfigKeyValue(QString key, QString value) override; virtual void parseConfigKeyValue(QString key, QString value) override;
virtual QMap<QString, QString> getKeyValueMap() override; virtual QMap<QString, QString> getKeyValueMap() override;
virtual void init() override {}; virtual void init() override {};
@ -318,9 +329,7 @@ enum ProjectFilePath {
class ProjectConfig: public KeyValueConfigBase class ProjectConfig: public KeyValueConfigBase
{ {
public: public:
ProjectConfig() { ProjectConfig();
reset();
}
virtual void reset() override { virtual void reset() override {
this->baseGameVersion = BaseGameVersion::pokeemerald; this->baseGameVersion = BaseGameVersion::pokeemerald;
// Reset non-version-specific settings // Reset non-version-specific settings
@ -365,6 +374,7 @@ public:
static QString getPlayerIconPath(BaseGameVersion baseGameVersion, int character); static QString getPlayerIconPath(BaseGameVersion baseGameVersion, int character);
static QIcon getPlayerIcon(BaseGameVersion baseGameVersion, int character); static QIcon getPlayerIcon(BaseGameVersion baseGameVersion, int character);
QString projectDir() const { return m_root; } // Alias for root()
void reset(BaseGameVersion baseGameVersion); void reset(BaseGameVersion baseGameVersion);
void setFilePath(ProjectFilePath pathId, const QString &path); void setFilePath(ProjectFilePath pathId, const QString &path);
void setFilePath(const QString &pathId, const QString &path); void setFilePath(const QString &pathId, const QString &path);
@ -387,7 +397,6 @@ public:
QMap<QString, QString> getPokemonIconPaths(); QMap<QString, QString> getPokemonIconPaths();
BaseGameVersion baseGameVersion; BaseGameVersion baseGameVersion;
QString projectDir;
bool usePoryScript; bool usePoryScript;
bool useCustomBorderSize; bool useCustomBorderSize;
bool eventWeatherTriggerEnabled; bool eventWeatherTriggerEnabled;
@ -435,7 +444,6 @@ public:
QMap<QString,QString> globalConstants; QMap<QString,QString> globalConstants;
protected: protected:
virtual QString getConfigFilepath() override;
virtual void parseConfigKeyValue(QString key, QString value) override; virtual void parseConfigKeyValue(QString key, QString value) override;
virtual QMap<QString, QString> getKeyValueMap() override; virtual QMap<QString, QString> getKeyValueMap() override;
virtual void init() override; virtual void init() override;
@ -454,27 +462,25 @@ extern ProjectConfig projectConfig;
class UserConfig: public KeyValueConfigBase class UserConfig: public KeyValueConfigBase
{ {
public: public:
UserConfig() { UserConfig();
reset();
}
virtual void reset() override { virtual void reset() override {
this->recentMapOrLayout = QString(); this->recentMapOrLayout = QString();
this->useEncounterJson = true; this->useEncounterJson = true;
this->customScripts.clear(); this->customScripts.clear();
this->readKeys.clear(); this->readKeys.clear();
} }
QString projectDir() const { return m_root; } // Alias for root()
void parseCustomScripts(QString input); void parseCustomScripts(QString input);
QString outputCustomScripts(); QString outputCustomScripts();
void setCustomScripts(QStringList scripts, QList<bool> enabled); void setCustomScripts(QStringList scripts, QList<bool> enabled);
QStringList getCustomScriptPaths(); QStringList getCustomScriptPaths();
QList<bool> getCustomScriptsEnabled(); QList<bool> getCustomScriptsEnabled();
QString projectDir;
QString recentMapOrLayout; QString recentMapOrLayout;
bool useEncounterJson; bool useEncounterJson;
protected: protected:
virtual QString getConfigFilepath() override;
virtual void parseConfigKeyValue(QString key, QString value) override; virtual void parseConfigKeyValue(QString key, QString value) override;
virtual QMap<QString, QString> getKeyValueMap() override; virtual QMap<QString, QString> getKeyValueMap() override;
virtual void init() override; virtual void init() override;
@ -496,10 +502,7 @@ class Shortcut;
class ShortcutsConfig : public KeyValueConfigBase class ShortcutsConfig : public KeyValueConfigBase
{ {
public: public:
ShortcutsConfig() : ShortcutsConfig();
user_shortcuts({ }),
default_shortcuts({ })
{ }
virtual void reset() override { user_shortcuts.clear(); } virtual void reset() override { user_shortcuts.clear(); }
@ -512,7 +515,6 @@ public:
QList<QKeySequence> userShortcuts(const QObject *object) const; QList<QKeySequence> userShortcuts(const QObject *object) const;
protected: protected:
virtual QString getConfigFilepath() override;
virtual void parseConfigKeyValue(QString key, QString value) override; virtual void parseConfigKeyValue(QString key, QString value) override;
virtual QMap<QString, QString> getKeyValueMap() override; virtual QMap<QString, QString> getKeyValueMap() override;
virtual void init() override { }; virtual void init() override { };

View File

@ -386,7 +386,6 @@ private:
void scrollMapListToCurrentLayout(MapTree *list); void scrollMapListToCurrentLayout(MapTree *list);
void scrollCurrentMapListToItem(const QString &itemName); void scrollCurrentMapListToItem(const QString &itemName);
void showFileWatcherWarning(); void showFileWatcherWarning();
QString getExistingDirectory(QString);
bool openProject(QString dir, bool initial = false); bool openProject(QString dir, bool initial = false);
bool closeProject(); bool closeProject();
void showRecentError(const QString &baseMessage); void showRecentError(const QString &baseMessage);

View File

@ -203,17 +203,26 @@ ProjectFilePath reverseDefaultPaths(QString str) {
return static_cast<ProjectFilePath>(-1); return static_cast<ProjectFilePath>(-1);
} }
KeyValueConfigBase::~KeyValueConfigBase() { void KeyValueConfigBase::setRoot(const QString &root) {
m_root = root;
QDir dir(m_root);
if (!m_root.isEmpty() && !dir.exists()) {
dir.mkpath(m_root);
}
m_filepath = dir.absoluteFilePath(m_filename);
} }
void KeyValueConfigBase::load() { bool KeyValueConfigBase::load(const QString &root) {
if (!root.isEmpty()) {
setRoot(root);
}
reset(); reset();
QFile file(this->getConfigFilepath()); QFile file(this->filepath());
if (!file.exists()) { if (file.exists() && !file.open(QIODevice::ReadOnly)) {
logError(QString("Could not open config file '%1': ").arg(this->filepath()) + file.errorString());
return false;
} else if (file.size() == 0) {
this->init(); this->init();
} else if (!file.open(QIODevice::ReadOnly)) {
logError(QString("Could not open config file '%1': ").arg(this->getConfigFilepath()) + file.errorString());
} }
QTextStream in(&file); QTextStream in(&file);
@ -231,7 +240,7 @@ void KeyValueConfigBase::load() {
QRegularExpressionMatch match = re.match(line); QRegularExpressionMatch match = re.match(line);
if (!match.hasMatch()) { if (!match.hasMatch()) {
logWarn(QString("Invalid config line in %1: '%2'").arg(this->getConfigFilepath()).arg(line)); logWarn(QString("Invalid config line in %1: '%2'").arg(this->filepath()).arg(line));
continue; continue;
} }
@ -240,6 +249,7 @@ void KeyValueConfigBase::load() {
this->setUnreadKeys(); this->setUnreadKeys();
file.close(); file.close();
return true;
} }
bool KeyValueConfigBase::save() { bool KeyValueConfigBase::save() {
@ -249,9 +259,9 @@ bool KeyValueConfigBase::save() {
text += QString("%1=%2\n").arg(it.key()).arg(it.value()); text += QString("%1=%2\n").arg(it.key()).arg(it.value());
} }
QFile file(this->getConfigFilepath()); QFile file(this->filepath());
if (!file.open(QIODevice::WriteOnly)) { if (!file.open(QIODevice::WriteOnly)) {
logError(QString("Could not open config file '%1' for writing: ").arg(this->getConfigFilepath()) + file.errorString()); logError(QString("Could not open config file '%1' for writing: ").arg(this->filepath()) + file.errorString());
return false; return false;
} }
@ -300,16 +310,9 @@ QColor KeyValueConfigBase::getConfigColor(const QString &key, const QString &val
PorymapConfig porymapConfig; PorymapConfig porymapConfig;
QString PorymapConfig::getConfigFilepath() { PorymapConfig::PorymapConfig() : KeyValueConfigBase(QStringLiteral("porymap.cfg")) {
// porymap config file is in the same directory as porymap itself. reset();
QString settingsPath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); setRoot(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) { void PorymapConfig::parseConfigKeyValue(QString key, QString value) {
@ -330,7 +333,7 @@ void PorymapConfig::parseConfigKeyValue(QString key, QString value) {
bool ok; bool ok;
int tab = key.mid(QStringLiteral("map_list_hide_empty_enabled/").length()).toInt(&ok, 0); int tab = key.mid(QStringLiteral("map_list_hide_empty_enabled/").length()).toInt(&ok, 0);
if (!ok) { if (!ok) {
logWarn(QString("Invalid config key found in config file %1: '%2'").arg(this->getConfigFilepath()).arg(key)); logWarn(QString("Invalid config key found in config file %1: '%2'").arg(this->filepath()).arg(key));
return; return;
} }
this->mapListHideEmptyEnabled.insert(tab, getConfigBool(key, value)); this->mapListHideEmptyEnabled.insert(tab, getConfigBool(key, value));
@ -485,7 +488,7 @@ void PorymapConfig::parseConfigKeyValue(QString key, QString value) {
this->statusBarLogTypes.insert(type); this->statusBarLogTypes.insert(type);
} }
} else { } else {
logWarn(QString("Invalid config key found in config file %1: '%2'").arg(this->getConfigFilepath()).arg(key)); logWarn(QString("Invalid config key found in config file %1: '%2'").arg(this->filepath()).arg(key));
} }
} }
@ -773,9 +776,8 @@ QIcon ProjectConfig::getPlayerIcon(BaseGameVersion baseGameVersion, int characte
ProjectConfig projectConfig; ProjectConfig projectConfig;
QString ProjectConfig::getConfigFilepath() { ProjectConfig::ProjectConfig() : KeyValueConfigBase(QStringLiteral("porymap.project.cfg")) {
// porymap config file is in the same directory as porymap itself. reset();
return QDir(this->projectDir).filePath("porymap.project.cfg");
} }
void ProjectConfig::parseConfigKeyValue(QString key, QString value) { void ProjectConfig::parseConfigKeyValue(QString key, QString value) {
@ -871,14 +873,14 @@ void ProjectConfig::parseConfigKeyValue(QString key, QString value) {
if (k != static_cast<ProjectFilePath>(-1)) { if (k != static_cast<ProjectFilePath>(-1)) {
this->setFilePath(k, value); this->setFilePath(k, value);
} else { } else {
logWarn(QString("Invalid config key found in config file %1: '%2'").arg(this->getConfigFilepath()).arg(key)); logWarn(QString("Invalid config key found in config file %1: '%2'").arg(this->filepath()).arg(key));
} }
} else if (key.startsWith("ident/")) { } else if (key.startsWith("ident/")) {
auto identifierId = reverseDefaultIdentifier(key.mid(QStringLiteral("ident/").length())); auto identifierId = reverseDefaultIdentifier(key.mid(QStringLiteral("ident/").length()));
if (identifierId != static_cast<ProjectIdentifier>(-1)) { if (identifierId != static_cast<ProjectIdentifier>(-1)) {
this->setIdentifier(identifierId, value); this->setIdentifier(identifierId, value);
} else { } else {
logWarn(QString("Invalid config key found in config file %1: '%2'").arg(this->getConfigFilepath()).arg(key)); logWarn(QString("Invalid config key found in config file %1: '%2'").arg(this->filepath()).arg(key));
} }
} else if (key.startsWith("global_constant/")) { } else if (key.startsWith("global_constant/")) {
this->globalConstants.insert(key.mid(QStringLiteral("global_constant/").length()), value); this->globalConstants.insert(key.mid(QStringLiteral("global_constant/").length()), value);
@ -935,7 +937,7 @@ void ProjectConfig::parseConfigKeyValue(QString key, QString value) {
} else if (key == "forced_major_version") { } else if (key == "forced_major_version") {
this->forcedMajorVersion = getConfigInteger(key, value); this->forcedMajorVersion = getConfigInteger(key, value);
} else { } else {
logWarn(QString("Invalid config key found in config file %1: '%2'").arg(this->getConfigFilepath()).arg(key)); logWarn(QString("Invalid config key found in config file %1: '%2'").arg(this->filepath()).arg(key));
} }
readKeys.append(key); readKeys.append(key);
} }
@ -1048,7 +1050,7 @@ QMap<QString, QString> ProjectConfig::getKeyValueMap() {
} }
void ProjectConfig::init() { void ProjectConfig::init() {
QString dirName = QDir(this->projectDir).dirName().toLower(); QString dirName = QDir(this->projectDir()).dirName().toLower();
BaseGameVersion version = stringToBaseGameVersion(dirName); BaseGameVersion version = stringToBaseGameVersion(dirName);
if (version != BaseGameVersion::none) { if (version != BaseGameVersion::none) {
@ -1107,7 +1109,7 @@ QString ProjectConfig::getFilePath(ProjectFilePath pathId) {
QString customPath = this->getCustomFilePath(pathId); QString customPath = this->getCustomFilePath(pathId);
if (!customPath.isEmpty()) { if (!customPath.isEmpty()) {
// A custom filepath has been specified. If the file/folder exists, use that. // A custom filepath has been specified. If the file/folder exists, use that.
const QString baseDir = this->projectDir + "/"; const QString baseDir = this->projectDir() + "/";
if (customPath.startsWith(baseDir)) { if (customPath.startsWith(baseDir)) {
customPath.remove(0, baseDir.length()); customPath.remove(0, baseDir.length());
} }
@ -1201,9 +1203,8 @@ QMap<QString, QString> ProjectConfig::getPokemonIconPaths() {
UserConfig userConfig; UserConfig userConfig;
QString UserConfig::getConfigFilepath() { UserConfig::UserConfig() : KeyValueConfigBase(QStringLiteral("porymap.user.cfg")) {
// porymap config file is in the same directory as porymap itself. reset();
return QDir(this->projectDir).filePath("porymap.user.cfg");
} }
void UserConfig::parseConfigKeyValue(QString key, QString value) { void UserConfig::parseConfigKeyValue(QString key, QString value) {
@ -1214,7 +1215,7 @@ void UserConfig::parseConfigKeyValue(QString key, QString value) {
} else if (key == "custom_scripts") { } else if (key == "custom_scripts") {
this->parseCustomScripts(value); this->parseCustomScripts(value);
} else { } else {
logWarn(QString("Invalid config key found in config file %1: '%2'").arg(this->getConfigFilepath()).arg(key)); logWarn(QString("Invalid config key found in config file %1: '%2'").arg(this->filepath()).arg(key));
} }
readKeys.append(key); readKeys.append(key);
} }
@ -1283,15 +1284,10 @@ QList<bool> UserConfig::getCustomScriptsEnabled() {
ShortcutsConfig shortcutsConfig; ShortcutsConfig shortcutsConfig;
QString ShortcutsConfig::getConfigFilepath() { ShortcutsConfig::ShortcutsConfig() : KeyValueConfigBase(QStringLiteral("porymap.shortcuts.cfg")),
QString settingsPath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); user_shortcuts({ }),
QDir dir(settingsPath); default_shortcuts({ }) {
if (!dir.exists()) setRoot(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
dir.mkpath(settingsPath);
QString configPath = dir.absoluteFilePath("porymap.shortcuts.cfg");
return configPath;
} }
void ShortcutsConfig::parseConfigKeyValue(QString key, QString value) { void ShortcutsConfig::parseConfigKeyValue(QString key, QString value) {

View File

@ -176,7 +176,7 @@ QStringList Map::getScriptLabels(Event::Group group) {
QString Map::getScriptsFilepath() const { QString Map::getScriptsFilepath() const {
const bool usePoryscript = projectConfig.usePoryScript; const bool usePoryscript = projectConfig.usePoryScript;
auto path = QDir::cleanPath(QString("%1/%2/%3/scripts") auto path = QDir::cleanPath(QString("%1/%2/%3/scripts")
.arg(projectConfig.projectDir) .arg(projectConfig.projectDir())
.arg(projectConfig.getFilePath(ProjectFilePath::data_map_folders)) .arg(projectConfig.getFilePath(ProjectFilePath::data_map_folders))
.arg(!m_sharedScriptsMap.isEmpty() ? m_sharedScriptsMap : m_name)); .arg(!m_sharedScriptsMap.isEmpty() ? m_sharedScriptsMap : m_name));
auto extension = Project::getScriptFileExtension(usePoryscript); auto extension = Project::getScriptFileExtension(usePoryscript);
@ -188,7 +188,7 @@ QString Map::getScriptsFilepath() const {
QString Map::getJsonFilepath(const QString &mapName) { QString Map::getJsonFilepath(const QString &mapName) {
return QDir::cleanPath(QString("%1/%2/%3/map.json") return QDir::cleanPath(QString("%1/%2/%3/map.json")
.arg(projectConfig.projectDir) .arg(projectConfig.projectDir())
.arg(projectConfig.getFilePath(ProjectFilePath::data_map_folders)) .arg(projectConfig.getFilePath(ProjectFilePath::data_map_folders))
.arg(mapName)); .arg(mapName));
} }

View File

@ -2339,7 +2339,7 @@ void Editor::openMapJson(const QString &mapName) const {
} }
void Editor::openLayoutJson(const QString &layoutId) const { void Editor::openLayoutJson(const QString &layoutId) const {
QString path = QDir::cleanPath(QString("%1/%2").arg(projectConfig.projectDir).arg(projectConfig.getFilePath(ProjectFilePath::json_layouts))); QString path = QDir::cleanPath(QString("%1/%2").arg(projectConfig.projectDir()).arg(projectConfig.getFilePath(ProjectFilePath::json_layouts)));
QString idField = QString("\"id\": \"%1\",").arg(layoutId); QString idField = QString("\"id\": \"%1\",").arg(layoutId);
openInTextEditor(path, ParseUtil::getJsonLineNumber(path, idField)); openInTextEditor(path, ParseUtil::getJsonLineNumber(path, idField));
} }

View File

@ -728,10 +728,11 @@ bool MainWindow::openProject(QString dir, bool initial) {
porysplash->start(); porysplash->start();
porysplash->showLoadingMessage("config"); porysplash->showLoadingMessage("config");
userConfig.projectDir = dir; if (!projectConfig.load(dir) || !userConfig.load(dir)) {
userConfig.load(); showProjectOpenFailure();
projectConfig.projectDir = dir; porysplash->stop();
projectConfig.load(); return false;
}
porysplash->showLoadingMessage("custom scripts"); porysplash->showLoadingMessage("custom scripts");
Scripting::init(this); Scripting::init(this);
@ -992,13 +993,8 @@ void MainWindow::showFileWatcherWarning() {
this->fileWatcherWarning->exec(); this->fileWatcherWarning->exec();
} }
QString MainWindow::getExistingDirectory(QString dir) { void MainWindow::on_action_Open_Project_triggered() {
return FileDialog::getExistingDirectory(this, "Open Directory", dir, QFileDialog::ShowDirsOnly); QString dir = FileDialog::getExistingDirectory(this, QStringLiteral("Choose Project Folder"));
}
void MainWindow::on_action_Open_Project_triggered()
{
QString dir = getExistingDirectory(!projectConfig.projectDir.isEmpty() ? userConfig.projectDir : ".");
if (!dir.isEmpty()) if (!dir.isEmpty())
openProject(dir); openProject(dir);
} }
@ -3010,7 +3006,7 @@ void MainWindow::reloadScriptEngine() {
Scripting::init(this); Scripting::init(this);
Scripting::populateGlobalObject(this); Scripting::populateGlobalObject(this);
// Lying to the scripts here, simulating a project reload // Lying to the scripts here, simulating a project reload
Scripting::cb_ProjectOpened(projectConfig.projectDir); Scripting::cb_ProjectOpened(projectConfig.projectDir());
if (this->editor) { if (this->editor) {
if (this->editor->layout) if (this->editor->layout)
Scripting::cb_LayoutOpened(this->editor->layout->name); Scripting::cb_LayoutOpened(this->editor->layout->name);

View File

@ -3375,7 +3375,7 @@ QString Project::getExistingFilepath(QString filepath) {
if (filepath.isEmpty() || QFile::exists(filepath)) if (filepath.isEmpty() || QFile::exists(filepath))
return filepath; return filepath;
filepath = QDir::cleanPath(projectConfig.projectDir + QDir::separator() + filepath); filepath = QDir::cleanPath(projectConfig.projectDir() + QDir::separator() + filepath);
if (QFile::exists(filepath)) if (QFile::exists(filepath))
return filepath; return filepath;

View File

@ -11,7 +11,7 @@
CustomScriptsEditor::CustomScriptsEditor(QWidget *parent) : CustomScriptsEditor::CustomScriptsEditor(QWidget *parent) :
QMainWindow(parent), QMainWindow(parent),
ui(new Ui::CustomScriptsEditor), ui(new Ui::CustomScriptsEditor),
baseDir(userConfig.projectDir + "/") baseDir(userConfig.projectDir() + "/")
{ {
ui->setupUi(this); ui->setupUi(this);
setAttribute(Qt::WA_DeleteOnClose); setAttribute(Qt::WA_DeleteOnClose);

View File

@ -94,7 +94,7 @@ void Prefab::savePrefabs() {
QFileInfo info(filepath); QFileInfo info(filepath);
if (info.isRelative()) { if (info.isRelative()) {
filepath = QDir::cleanPath(projectConfig.projectDir + QDir::separator() + filepath); filepath = QDir::cleanPath(projectConfig.projectDir() + QDir::separator() + filepath);
} }
QFile prefabsFile(filepath); QFile prefabsFile(filepath);
if (!prefabsFile.open(QIODevice::WriteOnly)) { if (!prefabsFile.open(QIODevice::WriteOnly)) {
@ -297,7 +297,7 @@ bool Prefab::tryImportDefaultPrefabs(QWidget * parent, BaseGameVersion version,
if (fileInfo.suffix().isEmpty()) if (fileInfo.suffix().isEmpty())
filepath += ".json"; filepath += ".json";
if (fileInfo.isRelative()) { if (fileInfo.isRelative()) {
absFilepath = QDir::cleanPath(projectConfig.projectDir + QDir::separator() + filepath); absFilepath = QDir::cleanPath(projectConfig.projectDir() + QDir::separator() + filepath);
} else { } else {
absFilepath = filepath; absFilepath = filepath;
} }

View File

@ -21,7 +21,7 @@ ProjectSettingsEditor::ProjectSettingsEditor(QWidget *parent, Project *project)
QMainWindow(parent), QMainWindow(parent),
ui(new Ui::ProjectSettingsEditor), ui(new Ui::ProjectSettingsEditor),
project(project), project(project),
baseDir(projectConfig.projectDir + "/") baseDir(projectConfig.projectDir() + "/")
{ {
ui->setupUi(this); ui->setupUi(this);
setAttribute(Qt::WA_DeleteOnClose); setAttribute(Qt::WA_DeleteOnClose);