Enforce project folder for custom filepaths

This commit is contained in:
GriffinR 2023-09-09 19:36:12 -04:00
parent 7a399daaff
commit a5a864926a
4 changed files with 66 additions and 24 deletions

View file

@ -274,8 +274,8 @@ public:
void setDefaultSecondaryTileset(QString tilesetName); void setDefaultSecondaryTileset(QString tilesetName);
void setFilePath(QString pathId, QString path); void setFilePath(QString pathId, QString path);
void setFilePath(ProjectFilePath pathId, QString path); void setFilePath(ProjectFilePath pathId, QString path);
QString getFilePath(QString defaultPath, bool allowDefault = true); QString getFilePath(QString defaultPath, bool customOnly = false);
QString getFilePath(ProjectFilePath pathId, bool allowDefault = true); QString getFilePath(ProjectFilePath pathId, bool customOnly = false);
void setPrefabFilepath(QString filepath); void setPrefabFilepath(QString filepath);
QString getPrefabFilepath(); QString getPrefabFilepath();
void setPrefabImportPrompted(bool prompted); void setPrefabImportPrompted(bool prompted);

View file

@ -30,6 +30,7 @@ private:
bool hasUnsavedChanges = false; bool hasUnsavedChanges = false;
bool projectNeedsReload = false; bool projectNeedsReload = false;
bool refreshing = false; bool refreshing = false;
const QString baseDir;
void initUi(); void initUi();
void connectSignals(); void connectSignals();
@ -42,6 +43,7 @@ private:
bool promptRestoreDefaults(); bool promptRestoreDefaults();
void createProjectPathsTable(); void createProjectPathsTable();
QString chooseProjectFile(const QString &defaultFilepath);
private slots: private slots:
void dialogButtonClicked(QAbstractButton *button); void dialogButtonClicked(QAbstractButton *button);

View file

@ -804,18 +804,29 @@ void ProjectConfig::setFilePath(QString defaultPath, QString newPath) {
this->setFilePath(reverseDefaultPaths(defaultPath), newPath); this->setFilePath(reverseDefaultPaths(defaultPath), newPath);
} }
QString ProjectConfig::getFilePath(ProjectFilePath pathId, bool allowDefault) { QString ProjectConfig::getFilePath(ProjectFilePath pathId, bool customOnly) {
if (this->filePaths.contains(pathId)) { const QString customPath = this->filePaths.value(pathId);
return this->filePaths[pathId];
} else if (allowDefault && defaultPaths.contains(pathId)) { // When reading custom filepaths for the settings editor we don't care
return defaultPaths[pathId].second; // about the default path or whether the custom path exists.
} else { if (customOnly)
return QString(); return customPath;
if (!customPath.isEmpty()) {
// A custom filepath has been specified. If the file/folder exists, use that.
const QString absCustomPath = this->projectDir + QDir::separator() + customPath;
if (QFileInfo::exists(absCustomPath)) {
return customPath;
} else {
logError(QString("Custom project filepath '%1' not found. Using default.").arg(absCustomPath));
}
} }
return defaultPaths.contains(pathId) ? defaultPaths[pathId].second : QString();
} }
QString ProjectConfig::getFilePath(QString defaultPath, bool allowDefault) { QString ProjectConfig::getFilePath(QString defaultPath, bool customOnly) {
return this->getFilePath(reverseDefaultPaths(defaultPath), allowDefault); return this->getFilePath(reverseDefaultPaths(defaultPath), customOnly);
} }
void ProjectConfig::setBaseGameVersion(BaseGameVersion baseGameVersion) { void ProjectConfig::setBaseGameVersion(BaseGameVersion baseGameVersion) {

View file

@ -14,7 +14,8 @@
ProjectSettingsEditor::ProjectSettingsEditor(QWidget *parent, Project *project) : ProjectSettingsEditor::ProjectSettingsEditor(QWidget *parent, Project *project) :
QMainWindow(parent), QMainWindow(parent),
ui(new Ui::ProjectSettingsEditor), ui(new Ui::ProjectSettingsEditor),
project(project) project(project),
baseDir(userConfig.getProjectDir() + QDir::separator())
{ {
ui->setupUi(this); ui->setupUi(this);
setAttribute(Qt::WA_DeleteOnClose); setAttribute(Qt::WA_DeleteOnClose);
@ -84,25 +85,54 @@ void ProjectSettingsEditor::createProjectPathsTable() {
name->setAlignment(Qt::AlignBottom); name->setAlignment(Qt::AlignBottom);
name->setText(pathPair.first); name->setText(pathPair.first);
// Editable area of the path // Filepath line edit
auto path = new QLineEdit(); auto lineEdit = new QLineEdit();
path->setObjectName(pathPair.first); // Used when saving the paths lineEdit->setObjectName(pathPair.first); // Used when saving the paths
path->setPlaceholderText(pathPair.second); lineEdit->setPlaceholderText(pathPair.second);
path->setClearButtonEnabled(true); lineEdit->setClearButtonEnabled(true);
// "Choose file" button
auto button = new QToolButton(); auto button = new QToolButton();
button->setIcon(QIcon(":/icons/folder.ico")); button->setIcon(QIcon(":/icons/folder.ico"));
// TODO: file prompt connect(button, &QAbstractButton::clicked, [this, lineEdit](bool) {
//connect(button, &QAbstractButton::clicked, this, &ProjectSettingsEditor::); const QString path = this->chooseProjectFile(lineEdit->placeholderText());
if (!path.isEmpty()) {
lineEdit->setText(path);
this->markEdited();
}
});
// Add to list // Add to list
auto editArea = new QWidget(); auto editArea = new QWidget();
auto layout = new QHBoxLayout(editArea); auto layout = new QHBoxLayout(editArea);
layout->addWidget(path); layout->addWidget(lineEdit);
layout->addWidget(button); layout->addWidget(button);
ui->layout_ProjectPaths->addRow(name, editArea); ui->layout_ProjectPaths->addRow(name, editArea);
} }
} }
QString ProjectSettingsEditor::chooseProjectFile(const QString &defaultFilepath) {
const QString startDir = this->baseDir + defaultFilepath;
QString path;
if (defaultFilepath.endsWith("/")){
// Default filepath is a folder, choose a new folder
path = QFileDialog::getExistingDirectory(this, "Choose Project File Folder", startDir) + QDir::separator();
} else{
// Default filepath is not a folder, choose a new file
path = QFileDialog::getOpenFileName(this, "Choose Project File", startDir);
}
if (!path.startsWith(this->baseDir)){
// Most of Porymap's file-parsing code for project files will assume that filepaths
// are relative to the root project folder, so we enforce that here.
QMessageBox::warning(this, "Failed to set custom filepath",
QString("Custom filepaths must be inside the root project folder '%1'").arg(this->baseDir));
return QString();
}
return path.remove(0, this->baseDir.length());
}
void ProjectSettingsEditor::restoreWindowState() { void ProjectSettingsEditor::restoreWindowState() {
logInfo("Restoring project settings editor geometry from previous session."); logInfo("Restoring project settings editor geometry from previous session.");
const QMap<QString, QByteArray> geometry = porymapConfig.getProjectSettingsEditorGeometry(); const QMap<QString, QByteArray> geometry = porymapConfig.getProjectSettingsEditorGeometry();
@ -149,7 +179,7 @@ void ProjectSettingsEditor::refresh() {
ui->lineEdit_BorderMetatiles->setText(projectConfig.getNewMapBorderMetatileIdsString()); ui->lineEdit_BorderMetatiles->setText(projectConfig.getNewMapBorderMetatileIdsString());
ui->lineEdit_PrefabsPath->setText(projectConfig.getPrefabFilepath()); ui->lineEdit_PrefabsPath->setText(projectConfig.getPrefabFilepath());
for (auto lineEdit : ui->scrollAreaContents_ProjectPaths->findChildren<QLineEdit*>()) for (auto lineEdit : ui->scrollAreaContents_ProjectPaths->findChildren<QLineEdit*>())
lineEdit->setText(projectConfig.getFilePath(lineEdit->objectName(), false)); lineEdit->setText(projectConfig.getFilePath(lineEdit->objectName(), true));
this->refreshing = false; // Allow signals this->refreshing = false; // Allow signals
} }
@ -221,9 +251,8 @@ void ProjectSettingsEditor::choosePrefabsFileClicked(bool) {
this->project->setImportExportPath(filepath); this->project->setImportExportPath(filepath);
// Display relative path if this file is in the project folder // Display relative path if this file is in the project folder
const QString projectDir = projectConfig.getProjectDir() + QDir::separator(); if (filepath.startsWith(this->baseDir))
if (filepath.startsWith(projectDir)) filepath.remove(0, this->baseDir.length());
filepath.remove(0, projectDir.length());
ui->lineEdit_PrefabsPath->setText(filepath); ui->lineEdit_PrefabsPath->setText(filepath);
this->hasUnsavedChanges = true; this->hasUnsavedChanges = true;
} }