From 1ed9b1ee10bb11938bea487eedb06dd9351c035d Mon Sep 17 00:00:00 2001 From: GriffinR Date: Wed, 9 Oct 2024 12:35:12 -0400 Subject: [PATCH 1/2] Correctly restore window focus for file dialogs --- include/core/filedialog.h | 53 ++++++++++++++++++++++++++ include/project.h | 2 - include/ui/customscriptseditor.h | 1 - include/ui/regionmappropertiesdialog.h | 3 +- porymap.pro | 2 + src/core/filedialog.cpp | 36 +++++++++++++++++ src/mainwindow.cpp | 12 ++---- src/project.cpp | 8 +--- src/ui/customscriptseditor.cpp | 17 ++------- src/ui/mapimageexporter.cpp | 7 ++-- src/ui/newtilesetdialog.cpp | 1 - src/ui/paletteeditor.cpp | 9 +---- src/ui/projectsettingseditor.cpp | 8 ++-- src/ui/regionmapeditor.cpp | 1 - src/ui/regionmappropertiesdialog.cpp | 19 ++++----- src/ui/tileseteditor.cpp | 46 ++++++++-------------- 16 files changed, 134 insertions(+), 91 deletions(-) create mode 100644 include/core/filedialog.h create mode 100644 src/core/filedialog.cpp diff --git a/include/core/filedialog.h b/include/core/filedialog.h new file mode 100644 index 000000000..374f243d2 --- /dev/null +++ b/include/core/filedialog.h @@ -0,0 +1,53 @@ +#ifndef FILEDIALOG_H +#define FILEDIALOG_H + +#include + +/* + Static QFileDialog functions will (unless otherwise specified) use native file dialogs. + In general this is good (we want our file dialogs to be visually seamless) but unfortunately + the native file dialogs ignore the parent widget, so in some cases they'll return focus to + the main window rather than the window that opened the file dialog. + + To make working around this a little easier we use this class, which will use the native + file dialog and manually return focus to the parent widget. + + It will also save the directory of the previous file selected in a file dialog, and if + no 'dir' argument is specified it will open new dialogs at that directory. + +*/ + +class FileDialog : public QFileDialog +{ +public: + FileDialog(QWidget *parent, Qt::WindowFlags flags) : QFileDialog(parent, flags) {}; + FileDialog(QWidget *parent = nullptr, + const QString &caption = QString(), + const QString &directory = QString(), + const QString &filter = QString()) : QFileDialog(parent, caption, directory, filter) {}; + + static void setDirectory(const QString &dir) { FileDialog::prevDirectory = dir; } + static QString getDirectory() { return FileDialog::prevDirectory; } + + static QString getOpenFileName(QWidget *parent = nullptr, + const QString &caption = QString(), + const QString &dir = QString(), + const QString &filter = QString(), + QString *selectedFilter = nullptr, + QFileDialog::Options options = Options()); + + static QString getSaveFileName(QWidget *parent = nullptr, + const QString &caption = QString(), + const QString &dir = QString(), + const QString &filter = QString(), + QString *selectedFilter = nullptr, + QFileDialog::Options options = Options()); + +private: + static QString prevDirectory; + static QString getDirectoryFromInput(const QString &dir); + static void setDirectoryFromFile(const QString &fileName); + static void restoreFocus(QWidget *parent); +}; + +#endif // FILEDIALOG_H diff --git a/include/project.h b/include/project.h index 9b90a450a..f9fc704de 100644 --- a/include/project.h +++ b/include/project.h @@ -76,7 +76,6 @@ class Project : public QObject QFileSystemWatcher fileWatcher; QMap modifiedFileTimestamps; bool usingAsmTilesets; - QString importExportPath; QSet disabledSettingsNames; int pokemonMinLevel; int pokemonMaxLevel; @@ -216,7 +215,6 @@ class Project : public QObject QString buildMetatileLabelsText(const QMap defines); QString findMetatileLabelsTileset(QString label); - void setImportExportPath(QString filename); static QString getExistingFilepath(QString filepath); void applyParsedLimits(); diff --git a/include/ui/customscriptseditor.h b/include/ui/customscriptseditor.h index 0e5d34898..c93c7b7db 100644 --- a/include/ui/customscriptseditor.h +++ b/include/ui/customscriptseditor.h @@ -31,7 +31,6 @@ public slots: Ui::CustomScriptsEditor *ui; bool hasUnsavedChanges = false; - QString fileDialogDir; const QString baseDir; void displayScript(const QString &filepath, bool enabled); diff --git a/include/ui/regionmappropertiesdialog.h b/include/ui/regionmappropertiesdialog.h index 6097d842c..3abacc64f 100644 --- a/include/ui/regionmappropertiesdialog.h +++ b/include/ui/regionmappropertiesdialog.h @@ -4,7 +4,6 @@ #include "orderedjson.h" #include -#include class Project; @@ -33,7 +32,7 @@ class RegionMapPropertiesDialog : public QDialog void hideMessages(); - QString browse(QString filter, QFileDialog::FileMode mode); + QString browse(QString filter); private slots: void on_browse_tilesetImagePath_clicked(); diff --git a/porymap.pro b/porymap.pro index 6b7fc59dd..51df62f10 100644 --- a/porymap.pro +++ b/porymap.pro @@ -25,6 +25,7 @@ SOURCES += src/core/block.cpp \ src/core/bitpacker.cpp \ src/core/blockdata.cpp \ src/core/events.cpp \ + src/core/filedialog.cpp \ src/core/heallocation.cpp \ src/core/imageexport.cpp \ src/core/map.cpp \ @@ -123,6 +124,7 @@ HEADERS += include/core/block.h \ include/core/bitpacker.h \ include/core/blockdata.h \ include/core/events.h \ + include/core/filedialog.h \ include/core/heallocation.h \ include/core/history.h \ include/core/imageexport.h \ diff --git a/src/core/filedialog.cpp b/src/core/filedialog.cpp new file mode 100644 index 000000000..9e17cce30 --- /dev/null +++ b/src/core/filedialog.cpp @@ -0,0 +1,36 @@ +#include "filedialog.h" + +QString FileDialog::prevDirectory; + + QString FileDialog::getDirectoryFromInput(const QString &dir) { + if (dir.isEmpty()) + return FileDialog::prevDirectory; + return dir; + } + +void FileDialog::setDirectoryFromFile(const QString &fileName) { + if (!fileName.isEmpty()) + FileDialog::prevDirectory = QFileInfo(fileName).absolutePath(); +} + +void FileDialog::restoreFocus(QWidget *parent) { + if (parent) { + parent->raise(); + parent->activateWindow(); + } +} + +QString FileDialog::getOpenFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options) { + const QString fileName = QFileDialog::getOpenFileName(parent, caption, getDirectoryFromInput(dir), filter, selectedFilter, options); + setDirectoryFromFile(fileName); + restoreFocus(parent); + return fileName; +} + +QString FileDialog::getSaveFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options) { + const QString fileName = QFileDialog::getSaveFileName(parent, caption, getDirectoryFromInput(dir), filter, selectedFilter, options); + setDirectoryFromFile(fileName); + restoreFocus(parent); + return fileName; +} + diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 93ed1dcb0..103d0fda3 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -19,8 +19,8 @@ #include "montabwidget.h" #include "imageexport.h" #include "newmapconnectiondialog.h" +#include "filedialog.h" -#include #include #include #include @@ -730,7 +730,7 @@ void MainWindow::openSubWindow(QWidget * window) { } QString MainWindow::getExistingDirectory(QString dir) { - return QFileDialog::getExistingDirectory(this, "Open Directory", dir, QFileDialog::ShowDirsOnly); + return FileDialog::getExistingDirectory(this, "Open Directory", dir, QFileDialog::ShowDirsOnly); } void MainWindow::on_action_Open_Project_triggered() @@ -2596,15 +2596,11 @@ void MainWindow::on_actionImport_Map_from_Advance_Map_1_92_triggered(){ void MainWindow::importMapFromAdvanceMap1_92() { - QString filepath = QFileDialog::getOpenFileName( - this, - QString("Import Map from Advance Map 1.92"), - this->editor->project->importExportPath, - "Advance Map 1.92 Map Files (*.map)"); + QString filepath = FileDialog::getOpenFileName(this, "Import Map from Advance Map 1.92", "", "Advance Map 1.92 Map Files (*.map)"); if (filepath.isEmpty()) { return; } - this->editor->project->setImportExportPath(filepath); + MapParser parser; bool error = false; MapLayout *mapLayout = parser.parse(filepath, &error, editor->project); diff --git a/src/project.cpp b/src/project.cpp index 5ffc3c43e..e569ac695 100644 --- a/src/project.cpp +++ b/src/project.cpp @@ -7,6 +7,7 @@ #include "tile.h" #include "tileset.h" #include "map.h" +#include "filedialog.h" #include "orderedjson.h" @@ -89,7 +90,7 @@ void Project::initSignals() { void Project::set_root(QString dir) { this->root = dir; - this->importExportPath = dir; + FileDialog::setDirectory(dir); this->parser.set_root(dir); } @@ -2829,11 +2830,6 @@ QString Project::getDynamicMapDefineName() { return prefix + projectConfig.getIdentifier(ProjectIdentifier::define_map_dynamic); } -void Project::setImportExportPath(QString filename) -{ - this->importExportPath = QFileInfo(filename).absolutePath(); -} - // If the provided filepath is an absolute path to an existing file, return filepath. // If not, and the provided filepath is a relative path from the project dir to an existing file, return the relative path. // Otherwise return empty string. diff --git a/src/ui/customscriptseditor.cpp b/src/ui/customscriptseditor.cpp index b7180b923..40195d184 100644 --- a/src/ui/customscriptseditor.cpp +++ b/src/ui/customscriptseditor.cpp @@ -4,9 +4,9 @@ #include "config.h" #include "editor.h" #include "shortcut.h" +#include "filedialog.h" #include -#include CustomScriptsEditor::CustomScriptsEditor(QWidget *parent) : QMainWindow(parent), @@ -23,8 +23,6 @@ CustomScriptsEditor::CustomScriptsEditor(QWidget *parent) : for (int i = 0; i < paths.length(); i++) this->displayScript(paths.at(i), enabled.at(i)); - this->fileDialogDir = userConfig.projectDir; - connect(ui->button_CreateNewScript, &QAbstractButton::clicked, this, &CustomScriptsEditor::createNewScript); connect(ui->button_LoadScript, &QAbstractButton::clicked, this, &CustomScriptsEditor::loadScript); connect(ui->button_RefreshScripts, &QAbstractButton::clicked, this, &CustomScriptsEditor::userRefreshScripts); @@ -147,19 +145,13 @@ bool CustomScriptsEditor::getScriptEnabled(QListWidgetItem * item) const { } QString CustomScriptsEditor::chooseScript(QString dir) { - return QFileDialog::getOpenFileName(this, "Choose Custom Script File", dir, "JavaScript Files (*.js)"); + return FileDialog::getOpenFileName(this, "Choose Custom Script File", dir, "JavaScript Files (*.js)"); } void CustomScriptsEditor::createNewScript() { - QString filepath = QFileDialog::getSaveFileName(this, "Create New Script File", this->fileDialogDir + "/new_script.js", "JavaScript Files (*.js)"); - - // QFileDialog::getSaveFileName returns focus to the main editor window when closed. Workaround for this below - this->raise(); - this->activateWindow(); - + const QString filepath = FileDialog::getSaveFileName(this, "Create New Script File", FileDialog::getDirectory() + "/new_script.js", "JavaScript Files (*.js)"); if (filepath.isEmpty()) return; - this->fileDialogDir = filepath; QFile scriptFile(filepath); if (!scriptFile.open(QIODevice::WriteOnly)) { @@ -179,10 +171,9 @@ void CustomScriptsEditor::createNewScript() { } void CustomScriptsEditor::loadScript() { - QString filepath = this->chooseScript(this->fileDialogDir); + QString filepath = this->chooseScript(FileDialog::getDirectory()); if (filepath.isEmpty()) return; - this->fileDialogDir = filepath; this->displayNewScript(filepath); } diff --git a/src/ui/mapimageexporter.cpp b/src/ui/mapimageexporter.cpp index 10194b8bd..c5b66e381 100644 --- a/src/ui/mapimageexporter.cpp +++ b/src/ui/mapimageexporter.cpp @@ -2,8 +2,8 @@ #include "ui_mapimageexporter.h" #include "qgifimage.h" #include "editcommands.h" +#include "filedialog.h" -#include #include #include #include @@ -65,13 +65,12 @@ void MapImageExporter::saveImage() { } QString defaultFilepath = QString("%1/%2.%3") - .arg(editor->project->importExportPath) + .arg(FileDialog::getDirectory()) .arg(defaultFilename) .arg(this->mode == ImageExporterMode::Timelapse ? "gif" : "png"); QString filter = this->mode == ImageExporterMode::Timelapse ? "Image Files (*.gif)" : "Image Files (*.png *.jpg *.bmp)"; - QString filepath = QFileDialog::getSaveFileName(this, title, defaultFilepath, filter); + QString filepath = FileDialog::getSaveFileName(this, title, defaultFilepath, filter); if (!filepath.isEmpty()) { - editor->project->setImportExportPath(filepath); switch (this->mode) { case ImageExporterMode::Normal: this->preview.save(filepath); diff --git a/src/ui/newtilesetdialog.cpp b/src/ui/newtilesetdialog.cpp index fa9518791..e9eee9464 100644 --- a/src/ui/newtilesetdialog.cpp +++ b/src/ui/newtilesetdialog.cpp @@ -1,6 +1,5 @@ #include "newtilesetdialog.h" #include "ui_newtilesetdialog.h" -#include #include "project.h" NewTilesetDialog::NewTilesetDialog(Project* project, QWidget *parent) : diff --git a/src/ui/paletteeditor.cpp b/src/ui/paletteeditor.cpp index 393f3a6e7..d570f540b 100644 --- a/src/ui/paletteeditor.cpp +++ b/src/ui/paletteeditor.cpp @@ -3,8 +3,8 @@ #include "paletteutil.h" #include "config.h" #include "log.h" +#include "filedialog.h" -#include #include @@ -158,15 +158,10 @@ void PaletteEditor::on_actionRedo_triggered() void PaletteEditor::on_actionImport_Palette_triggered() { - QString filepath = QFileDialog::getOpenFileName( - this, - QString("Import Tileset Palette"), - this->project->importExportPath, - "Palette Files (*.pal *.act *tpl *gpl)"); + QString filepath = FileDialog::getOpenFileName(this, "Import Tileset Palette", "", "Palette Files (*.pal *.act *tpl *gpl)"); if (filepath.isEmpty()) { return; } - this->project->setImportExportPath(filepath); bool error = false; QList palette = PaletteUtil::parse(filepath, &error); if (error) { diff --git a/src/ui/projectsettingseditor.cpp b/src/ui/projectsettingseditor.cpp index d84ef56b9..ec4765584 100644 --- a/src/ui/projectsettingseditor.cpp +++ b/src/ui/projectsettingseditor.cpp @@ -2,6 +2,7 @@ #include "config.h" #include "noscrollcombobox.h" #include "prefab.h" +#include "filedialog.h" #include #include @@ -383,10 +384,10 @@ QString ProjectSettingsEditor::chooseProjectFile(const QString &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(); + path = FileDialog::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); + path = FileDialog::getOpenFileName(this, "Choose Project File", startDir); } if (!path.startsWith(this->baseDir)){ @@ -573,10 +574,9 @@ void ProjectSettingsEditor::chooseImageFile(QLineEdit * filepathEdit) { } void ProjectSettingsEditor::chooseFile(QLineEdit * filepathEdit, const QString &description, const QString &extensions) { - QString filepath = QFileDialog::getOpenFileName(this, description, this->project->importExportPath, extensions); + QString filepath = FileDialog::getOpenFileName(this, description, "", extensions); if (filepath.isEmpty()) return; - this->project->setImportExportPath(filepath); if (filepathEdit) filepathEdit->setText(this->stripProjectDir(filepath)); diff --git a/src/ui/regionmapeditor.cpp b/src/ui/regionmapeditor.cpp index 372c6e052..b2a585368 100644 --- a/src/ui/regionmapeditor.cpp +++ b/src/ui/regionmapeditor.cpp @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include diff --git a/src/ui/regionmappropertiesdialog.cpp b/src/ui/regionmappropertiesdialog.cpp index 9c49def0d..10ce3c4a4 100644 --- a/src/ui/regionmappropertiesdialog.cpp +++ b/src/ui/regionmappropertiesdialog.cpp @@ -1,6 +1,7 @@ #include "project.h" #include "regionmappropertiesdialog.h" #include "ui_regionmappropertiesdialog.h" +#include "filedialog.h" RegionMapPropertiesDialog::RegionMapPropertiesDialog(QWidget *parent) : QDialog(parent), @@ -30,13 +31,9 @@ void RegionMapPropertiesDialog::hideMessages() { this->adjustSize(); } -QString RegionMapPropertiesDialog::browse(QString filter, QFileDialog::FileMode mode) { +QString RegionMapPropertiesDialog::browse(QString filter) { if (!this->project) return QString(); - QFileDialog browser; - browser.setFileMode(mode); - QString filepath = browser.getOpenFileName(this, "Select a File", this->project->importExportPath, filter); - if (!filepath.isEmpty()) - this->project->setImportExportPath(filepath); + QString filepath = FileDialog::getOpenFileName(this, "Select a File", "", filter); // remove the project root from the filepath return filepath.replace(this->project->root + "/", ""); @@ -107,21 +104,21 @@ poryjson::Json RegionMapPropertiesDialog::saveToJson() { } void RegionMapPropertiesDialog::on_browse_tilesetImagePath_clicked() { - QString path = browse("Images (*.png *.bmp)", QFileDialog::ExistingFile); + QString path = browse("Images (*.png *.bmp)"); if (!path.isEmpty()) { ui->config_tilemapImagePath->setText(path); } } void RegionMapPropertiesDialog::on_browse_tilemapBinPath_clicked() { - QString path = browse("Binary (*.bin *.tilemap *.4bpp *.8bpp)", QFileDialog::AnyFile); + QString path = browse("Binary (*.bin *.tilemap *.4bpp *.8bpp)"); if (!path.isEmpty()) { ui->config_tilemapBinPath->setText(path); } } void RegionMapPropertiesDialog::on_browse_tilemapPalettePath_clicked() { - QString path = browse("Text (*.pal)", QFileDialog::AnyFile); + QString path = browse("Text (*.pal)"); if (!path.isEmpty()) { ui->config_tilemapPalettePath->setText(path); } @@ -129,12 +126,12 @@ void RegionMapPropertiesDialog::on_browse_tilemapPalettePath_clicked() { void RegionMapPropertiesDialog::on_browse_layoutPath_clicked() { if (ui->config_layoutFormat->currentIndex() == 0) { - QString path = browse("Text File (*.h *.c *.inc *.txt)", QFileDialog::AnyFile); + QString path = browse("Text File (*.h *.c *.inc *.txt)"); if (!path.isEmpty()) { ui->config_layoutPath->setText(path); } } else { - QString path = browse("Binary (*.bin)", QFileDialog::AnyFile); + QString path = browse("Binary (*.bin)"); if (!path.isEmpty()) { ui->config_layoutPath->setText(path); } diff --git a/src/ui/tileseteditor.cpp b/src/ui/tileseteditor.cpp index 60a469e09..288c7bb63 100644 --- a/src/ui/tileseteditor.cpp +++ b/src/ui/tileseteditor.cpp @@ -7,7 +7,7 @@ #include "imageexport.h" #include "config.h" #include "shortcut.h" -#include +#include "filedialog.h" #include #include #include @@ -637,15 +637,11 @@ void TilesetEditor::importTilesetTiles(Tileset *tileset, bool primary) { QString descriptor = primary ? "primary" : "secondary"; QString descriptorCaps = primary ? "Primary" : "Secondary"; - QString filepath = QFileDialog::getOpenFileName( - this, - QString("Import %1 Tileset Tiles Image").arg(descriptorCaps), - this->project->importExportPath, - "Image Files (*.png *.bmp *.jpg *.dib)"); + QString filepath = FileDialog::getOpenFileName(this, QString("Import %1 Tileset Tiles Image").arg(descriptorCaps), "", "Image Files (*.png *.bmp *.jpg *.dib)"); if (filepath.isEmpty()) { return; } - this->project->setImportExportPath(filepath); + logInfo(QString("Importing %1 tileset tiles '%2'").arg(descriptor).arg(filepath)); // Read image data from buffer so that the built-in QImage doesn't try to detect file format @@ -698,15 +694,11 @@ void TilesetEditor::importTilesetTiles(Tileset *tileset, bool primary) { msgBox.setIcon(QMessageBox::Icon::Warning); msgBox.exec(); - QString filepath = QFileDialog::getOpenFileName( - this, - QString("Select Palette for Tiles Image").arg(descriptorCaps), - this->project->importExportPath, - "Palette Files (*.pal *.act *tpl *gpl)"); + QString filepath = FileDialog::getOpenFileName(this, "Select Palette for Tiles Image", "", "Palette Files (*.pal *.act *tpl *gpl)"); if (filepath.isEmpty()) { return; } - this->project->setImportExportPath(filepath); + bool error = false; QList palette = PaletteUtil::parse(filepath, &error); if (error) { @@ -939,10 +931,9 @@ void TilesetEditor::pasteMetatile(const Metatile * toPaste, QString newLabel) void TilesetEditor::on_actionExport_Primary_Tiles_Image_triggered() { QString defaultName = QString("%1_Tiles_Pal%2").arg(this->primaryTileset->name).arg(this->paletteId); - QString defaultFilepath = QString("%1/%2.png").arg(this->project->importExportPath).arg(defaultName); - QString filepath = QFileDialog::getSaveFileName(this, "Export Primary Tiles Image", defaultFilepath, "Image Files (*.png)"); + QString defaultFilepath = QString("%1/%2.png").arg(FileDialog::getDirectory()).arg(defaultName); + QString filepath = FileDialog::getSaveFileName(this, "Export Primary Tiles Image", defaultFilepath, "Image Files (*.png)"); if (!filepath.isEmpty()) { - this->project->setImportExportPath(filepath); QImage image = this->tileSelector->buildPrimaryTilesIndexedImage(); exportIndexed4BPPPng(image, filepath); } @@ -951,10 +942,9 @@ void TilesetEditor::on_actionExport_Primary_Tiles_Image_triggered() void TilesetEditor::on_actionExport_Secondary_Tiles_Image_triggered() { QString defaultName = QString("%1_Tiles_Pal%2").arg(this->secondaryTileset->name).arg(this->paletteId); - QString defaultFilepath = QString("%1/%2.png").arg(this->project->importExportPath).arg(defaultName); - QString filepath = QFileDialog::getSaveFileName(this, "Export Secondary Tiles Image", defaultFilepath, "Image Files (*.png)"); + QString defaultFilepath = QString("%1/%2.png").arg(FileDialog::getDirectory()).arg(defaultName); + QString filepath = FileDialog::getSaveFileName(this, "Export Secondary Tiles Image", defaultFilepath, "Image Files (*.png)"); if (!filepath.isEmpty()) { - this->project->setImportExportPath(filepath); QImage image = this->tileSelector->buildSecondaryTilesIndexedImage(); exportIndexed4BPPPng(image, filepath); } @@ -963,10 +953,9 @@ void TilesetEditor::on_actionExport_Secondary_Tiles_Image_triggered() void TilesetEditor::on_actionExport_Primary_Metatiles_Image_triggered() { QString defaultName = QString("%1_Metatiles").arg(this->primaryTileset->name); - QString defaultFilepath = QString("%1/%2.png").arg(this->project->importExportPath).arg(defaultName); - QString filepath = QFileDialog::getSaveFileName(this, "Export Primary Metatiles Image", defaultFilepath, "Image Files (*.png)"); + QString defaultFilepath = QString("%1/%2.png").arg(FileDialog::getDirectory()).arg(defaultName); + QString filepath = FileDialog::getSaveFileName(this, "Export Primary Metatiles Image", defaultFilepath, "Image Files (*.png)"); if (!filepath.isEmpty()) { - this->project->setImportExportPath(filepath); QImage image = this->metatileSelector->buildPrimaryMetatilesImage(); image.save(filepath, "PNG"); } @@ -975,10 +964,9 @@ void TilesetEditor::on_actionExport_Primary_Metatiles_Image_triggered() void TilesetEditor::on_actionExport_Secondary_Metatiles_Image_triggered() { QString defaultName = QString("%1_Metatiles").arg(this->secondaryTileset->name); - QString defaultFilepath = QString("%1/%2.png").arg(this->project->importExportPath).arg(defaultName); - QString filepath = QFileDialog::getSaveFileName(this, "Export Secondary Metatiles Image", defaultFilepath, "Image Files (*.png)"); + QString defaultFilepath = QString("%1/%2.png").arg(FileDialog::getDirectory()).arg(defaultName); + QString filepath = FileDialog::getSaveFileName(this, "Export Secondary Metatiles Image", defaultFilepath, "Image Files (*.png)"); if (!filepath.isEmpty()) { - this->project->setImportExportPath(filepath); QImage image = this->metatileSelector->buildSecondaryMetatilesImage(); image.save(filepath, "PNG"); } @@ -998,15 +986,11 @@ void TilesetEditor::importTilesetMetatiles(Tileset *tileset, bool primary) { QString descriptorCaps = primary ? "Primary" : "Secondary"; - QString filepath = QFileDialog::getOpenFileName( - this, - QString("Import %1 Tileset Metatiles from Advance Map 1.92").arg(descriptorCaps), - this->project->importExportPath, - "Advance Map 1.92 Metatile Files (*.bvd)"); + QString filepath = FileDialog::getOpenFileName(this, QString("Import %1 Tileset Metatiles from Advance Map 1.92").arg(descriptorCaps), "", "Advance Map 1.92 Metatile Files (*.bvd)"); if (filepath.isEmpty()) { return; } - this->project->setImportExportPath(filepath); + bool error = false; QList metatiles = MetatileParser::parse(filepath, &error, primary); if (error) { From f192b745ddf274ad202f02a03b027a31cd70946d Mon Sep 17 00:00:00 2001 From: GriffinR Date: Thu, 10 Oct 2024 01:43:35 -0400 Subject: [PATCH 2/2] Add additional static functions to filedialog --- include/core/filedialog.h | 12 ++++++++++++ src/core/filedialog.cpp | 15 +++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/include/core/filedialog.h b/include/core/filedialog.h index 374f243d2..a02f6193f 100644 --- a/include/core/filedialog.h +++ b/include/core/filedialog.h @@ -36,6 +36,18 @@ class FileDialog : public QFileDialog QString *selectedFilter = nullptr, QFileDialog::Options options = Options()); + static QStringList getOpenFileNames(QWidget *parent = nullptr, + const QString &caption = QString(), + const QString &dir = QString(), + const QString &filter = QString(), + QString *selectedFilter = nullptr, + QFileDialog::Options options = Options()); + + static QString getExistingDirectory(QWidget *parent = nullptr, + const QString &caption = QString(), + const QString &dir = QString(), + QFileDialog::Options options = ShowDirsOnly); + static QString getSaveFileName(QWidget *parent = nullptr, const QString &caption = QString(), const QString &dir = QString(), diff --git a/src/core/filedialog.cpp b/src/core/filedialog.cpp index 9e17cce30..94826090d 100644 --- a/src/core/filedialog.cpp +++ b/src/core/filedialog.cpp @@ -27,6 +27,14 @@ QString FileDialog::getOpenFileName(QWidget *parent, const QString &caption, con return fileName; } +QStringList FileDialog::getOpenFileNames(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options) { + const QStringList fileNames = QFileDialog::getOpenFileNames(parent, caption, getDirectoryFromInput(dir), filter, selectedFilter, options); + if (!fileNames.isEmpty()) + setDirectoryFromFile(fileNames.last()); + restoreFocus(parent); + return fileNames; +} + QString FileDialog::getSaveFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options) { const QString fileName = QFileDialog::getSaveFileName(parent, caption, getDirectoryFromInput(dir), filter, selectedFilter, options); setDirectoryFromFile(fileName); @@ -34,3 +42,10 @@ QString FileDialog::getSaveFileName(QWidget *parent, const QString &caption, con return fileName; } +QString FileDialog::getExistingDirectory(QWidget *parent, const QString &caption, const QString &dir, QFileDialog::Options options) { + const QString existingDir = QFileDialog::getExistingDirectory(parent, caption, getDirectoryFromInput(dir), options); + if (!existingDir.isEmpty()) + setDirectory(existingDir); + restoreFocus(parent); + return existingDir; +}