Merge pull request #621 from GriffinRichards/file-dialogs

Correctly restore window focus for file dialogs
This commit is contained in:
GriffinR 2024-10-16 10:41:17 -04:00 committed by GitHub
commit e431c161e7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 161 additions and 91 deletions

65
include/core/filedialog.h Normal file
View file

@ -0,0 +1,65 @@
#ifndef FILEDIALOG_H
#define FILEDIALOG_H
#include <QFileDialog>
/*
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 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(),
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

View file

@ -76,7 +76,6 @@ public:
QFileSystemWatcher fileWatcher; QFileSystemWatcher fileWatcher;
QMap<QString, qint64> modifiedFileTimestamps; QMap<QString, qint64> modifiedFileTimestamps;
bool usingAsmTilesets; bool usingAsmTilesets;
QString importExportPath;
QSet<QString> disabledSettingsNames; QSet<QString> disabledSettingsNames;
int pokemonMinLevel; int pokemonMinLevel;
int pokemonMaxLevel; int pokemonMaxLevel;
@ -216,7 +215,6 @@ public:
QString buildMetatileLabelsText(const QMap<QString, uint16_t> defines); QString buildMetatileLabelsText(const QMap<QString, uint16_t> defines);
QString findMetatileLabelsTileset(QString label); QString findMetatileLabelsTileset(QString label);
void setImportExportPath(QString filename);
static QString getExistingFilepath(QString filepath); static QString getExistingFilepath(QString filepath);
void applyParsedLimits(); void applyParsedLimits();

View file

@ -31,7 +31,6 @@ private:
Ui::CustomScriptsEditor *ui; Ui::CustomScriptsEditor *ui;
bool hasUnsavedChanges = false; bool hasUnsavedChanges = false;
QString fileDialogDir;
const QString baseDir; const QString baseDir;
void displayScript(const QString &filepath, bool enabled); void displayScript(const QString &filepath, bool enabled);

View file

@ -4,7 +4,6 @@
#include "orderedjson.h" #include "orderedjson.h"
#include <QDialog> #include <QDialog>
#include <QFileDialog>
class Project; class Project;
@ -33,7 +32,7 @@ private:
void hideMessages(); void hideMessages();
QString browse(QString filter, QFileDialog::FileMode mode); QString browse(QString filter);
private slots: private slots:
void on_browse_tilesetImagePath_clicked(); void on_browse_tilesetImagePath_clicked();

View file

@ -25,6 +25,7 @@ SOURCES += src/core/block.cpp \
src/core/bitpacker.cpp \ src/core/bitpacker.cpp \
src/core/blockdata.cpp \ src/core/blockdata.cpp \
src/core/events.cpp \ src/core/events.cpp \
src/core/filedialog.cpp \
src/core/heallocation.cpp \ src/core/heallocation.cpp \
src/core/imageexport.cpp \ src/core/imageexport.cpp \
src/core/map.cpp \ src/core/map.cpp \
@ -123,6 +124,7 @@ HEADERS += include/core/block.h \
include/core/bitpacker.h \ include/core/bitpacker.h \
include/core/blockdata.h \ include/core/blockdata.h \
include/core/events.h \ include/core/events.h \
include/core/filedialog.h \
include/core/heallocation.h \ include/core/heallocation.h \
include/core/history.h \ include/core/history.h \
include/core/imageexport.h \ include/core/imageexport.h \

51
src/core/filedialog.cpp Normal file
View file

@ -0,0 +1,51 @@
#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;
}
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);
restoreFocus(parent);
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;
}

View file

@ -19,8 +19,8 @@
#include "montabwidget.h" #include "montabwidget.h"
#include "imageexport.h" #include "imageexport.h"
#include "newmapconnectiondialog.h" #include "newmapconnectiondialog.h"
#include "filedialog.h"
#include <QFileDialog>
#include <QClipboard> #include <QClipboard>
#include <QDirIterator> #include <QDirIterator>
#include <QStandardItemModel> #include <QStandardItemModel>
@ -730,7 +730,7 @@ void MainWindow::openSubWindow(QWidget * window) {
} }
QString MainWindow::getExistingDirectory(QString dir) { 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() 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() void MainWindow::importMapFromAdvanceMap1_92()
{ {
QString filepath = QFileDialog::getOpenFileName( QString filepath = FileDialog::getOpenFileName(this, "Import Map from Advance Map 1.92", "", "Advance Map 1.92 Map Files (*.map)");
this,
QString("Import Map from Advance Map 1.92"),
this->editor->project->importExportPath,
"Advance Map 1.92 Map Files (*.map)");
if (filepath.isEmpty()) { if (filepath.isEmpty()) {
return; return;
} }
this->editor->project->setImportExportPath(filepath);
MapParser parser; MapParser parser;
bool error = false; bool error = false;
MapLayout *mapLayout = parser.parse(filepath, &error, editor->project); MapLayout *mapLayout = parser.parse(filepath, &error, editor->project);

View file

@ -7,6 +7,7 @@
#include "tile.h" #include "tile.h"
#include "tileset.h" #include "tileset.h"
#include "map.h" #include "map.h"
#include "filedialog.h"
#include "orderedjson.h" #include "orderedjson.h"
@ -89,7 +90,7 @@ void Project::initSignals() {
void Project::set_root(QString dir) { void Project::set_root(QString dir) {
this->root = dir; this->root = dir;
this->importExportPath = dir; FileDialog::setDirectory(dir);
this->parser.set_root(dir); this->parser.set_root(dir);
} }
@ -2829,11 +2830,6 @@ QString Project::getDynamicMapDefineName() {
return prefix + projectConfig.getIdentifier(ProjectIdentifier::define_map_dynamic); 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 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. // 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. // Otherwise return empty string.

View file

@ -4,9 +4,9 @@
#include "config.h" #include "config.h"
#include "editor.h" #include "editor.h"
#include "shortcut.h" #include "shortcut.h"
#include "filedialog.h"
#include <QDir> #include <QDir>
#include <QFileDialog>
CustomScriptsEditor::CustomScriptsEditor(QWidget *parent) : CustomScriptsEditor::CustomScriptsEditor(QWidget *parent) :
QMainWindow(parent), QMainWindow(parent),
@ -23,8 +23,6 @@ CustomScriptsEditor::CustomScriptsEditor(QWidget *parent) :
for (int i = 0; i < paths.length(); i++) for (int i = 0; i < paths.length(); i++)
this->displayScript(paths.at(i), enabled.at(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_CreateNewScript, &QAbstractButton::clicked, this, &CustomScriptsEditor::createNewScript);
connect(ui->button_LoadScript, &QAbstractButton::clicked, this, &CustomScriptsEditor::loadScript); connect(ui->button_LoadScript, &QAbstractButton::clicked, this, &CustomScriptsEditor::loadScript);
connect(ui->button_RefreshScripts, &QAbstractButton::clicked, this, &CustomScriptsEditor::userRefreshScripts); connect(ui->button_RefreshScripts, &QAbstractButton::clicked, this, &CustomScriptsEditor::userRefreshScripts);
@ -147,19 +145,13 @@ bool CustomScriptsEditor::getScriptEnabled(QListWidgetItem * item) const {
} }
QString CustomScriptsEditor::chooseScript(QString dir) { 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() { void CustomScriptsEditor::createNewScript() {
QString filepath = QFileDialog::getSaveFileName(this, "Create New Script File", this->fileDialogDir + "/new_script.js", "JavaScript Files (*.js)"); const QString filepath = FileDialog::getSaveFileName(this, "Create New Script File", FileDialog::getDirectory() + "/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();
if (filepath.isEmpty()) if (filepath.isEmpty())
return; return;
this->fileDialogDir = filepath;
QFile scriptFile(filepath); QFile scriptFile(filepath);
if (!scriptFile.open(QIODevice::WriteOnly)) { if (!scriptFile.open(QIODevice::WriteOnly)) {
@ -179,10 +171,9 @@ void CustomScriptsEditor::createNewScript() {
} }
void CustomScriptsEditor::loadScript() { void CustomScriptsEditor::loadScript() {
QString filepath = this->chooseScript(this->fileDialogDir); QString filepath = this->chooseScript(FileDialog::getDirectory());
if (filepath.isEmpty()) if (filepath.isEmpty())
return; return;
this->fileDialogDir = filepath;
this->displayNewScript(filepath); this->displayNewScript(filepath);
} }

View file

@ -2,8 +2,8 @@
#include "ui_mapimageexporter.h" #include "ui_mapimageexporter.h"
#include "qgifimage.h" #include "qgifimage.h"
#include "editcommands.h" #include "editcommands.h"
#include "filedialog.h"
#include <QFileDialog>
#include <QImage> #include <QImage>
#include <QPainter> #include <QPainter>
#include <QPoint> #include <QPoint>
@ -98,13 +98,12 @@ void MapImageExporter::saveImage() {
} }
QString defaultFilepath = QString("%1/%2.%3") QString defaultFilepath = QString("%1/%2.%3")
.arg(editor->project->importExportPath) .arg(FileDialog::getDirectory())
.arg(defaultFilename) .arg(defaultFilename)
.arg(this->mode == ImageExporterMode::Timelapse ? "gif" : "png"); .arg(this->mode == ImageExporterMode::Timelapse ? "gif" : "png");
QString filter = this->mode == ImageExporterMode::Timelapse ? "Image Files (*.gif)" : "Image Files (*.png *.jpg *.bmp)"; 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()) { if (!filepath.isEmpty()) {
editor->project->setImportExportPath(filepath);
switch (this->mode) { switch (this->mode) {
case ImageExporterMode::Normal: case ImageExporterMode::Normal:
case ImageExporterMode::Stitch: case ImageExporterMode::Stitch:

View file

@ -1,6 +1,5 @@
#include "newtilesetdialog.h" #include "newtilesetdialog.h"
#include "ui_newtilesetdialog.h" #include "ui_newtilesetdialog.h"
#include <QFileDialog>
#include "project.h" #include "project.h"
NewTilesetDialog::NewTilesetDialog(Project* project, QWidget *parent) : NewTilesetDialog::NewTilesetDialog(Project* project, QWidget *parent) :

View file

@ -3,8 +3,8 @@
#include "paletteutil.h" #include "paletteutil.h"
#include "config.h" #include "config.h"
#include "log.h" #include "log.h"
#include "filedialog.h"
#include <QFileDialog>
#include <QMessageBox> #include <QMessageBox>
@ -158,15 +158,10 @@ void PaletteEditor::on_actionRedo_triggered()
void PaletteEditor::on_actionImport_Palette_triggered() void PaletteEditor::on_actionImport_Palette_triggered()
{ {
QString filepath = QFileDialog::getOpenFileName( QString filepath = FileDialog::getOpenFileName(this, "Import Tileset Palette", "", "Palette Files (*.pal *.act *tpl *gpl)");
this,
QString("Import Tileset Palette"),
this->project->importExportPath,
"Palette Files (*.pal *.act *tpl *gpl)");
if (filepath.isEmpty()) { if (filepath.isEmpty()) {
return; return;
} }
this->project->setImportExportPath(filepath);
bool error = false; bool error = false;
QList<QRgb> palette = PaletteUtil::parse(filepath, &error); QList<QRgb> palette = PaletteUtil::parse(filepath, &error);
if (error) { if (error) {

View file

@ -2,6 +2,7 @@
#include "config.h" #include "config.h"
#include "noscrollcombobox.h" #include "noscrollcombobox.h"
#include "prefab.h" #include "prefab.h"
#include "filedialog.h"
#include <QAbstractButton> #include <QAbstractButton>
#include <QFormLayout> #include <QFormLayout>
@ -383,10 +384,10 @@ QString ProjectSettingsEditor::chooseProjectFile(const QString &defaultFilepath)
QString path; QString path;
if (defaultFilepath.endsWith("/")){ if (defaultFilepath.endsWith("/")){
// Default filepath is a folder, choose a new folder // 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{ } else{
// Default filepath is not a folder, choose a new file // 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)){ 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) { 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()) if (filepath.isEmpty())
return; return;
this->project->setImportExportPath(filepath);
if (filepathEdit) if (filepathEdit)
filepathEdit->setText(this->stripProjectDir(filepath)); filepathEdit->setText(this->stripProjectDir(filepath));

View file

@ -10,7 +10,6 @@
#include <QDir> #include <QDir>
#include <QDialog> #include <QDialog>
#include <QDialogButtonBox> #include <QDialogButtonBox>
#include <QFileDialog>
#include <QFormLayout> #include <QFormLayout>
#include <QLineEdit> #include <QLineEdit>
#include <QSpinBox> #include <QSpinBox>

View file

@ -1,6 +1,7 @@
#include "project.h" #include "project.h"
#include "regionmappropertiesdialog.h" #include "regionmappropertiesdialog.h"
#include "ui_regionmappropertiesdialog.h" #include "ui_regionmappropertiesdialog.h"
#include "filedialog.h"
RegionMapPropertiesDialog::RegionMapPropertiesDialog(QWidget *parent) : RegionMapPropertiesDialog::RegionMapPropertiesDialog(QWidget *parent) :
QDialog(parent), QDialog(parent),
@ -30,13 +31,9 @@ void RegionMapPropertiesDialog::hideMessages() {
this->adjustSize(); this->adjustSize();
} }
QString RegionMapPropertiesDialog::browse(QString filter, QFileDialog::FileMode mode) { QString RegionMapPropertiesDialog::browse(QString filter) {
if (!this->project) return QString(); if (!this->project) return QString();
QFileDialog browser; QString filepath = FileDialog::getOpenFileName(this, "Select a File", "", filter);
browser.setFileMode(mode);
QString filepath = browser.getOpenFileName(this, "Select a File", this->project->importExportPath, filter);
if (!filepath.isEmpty())
this->project->setImportExportPath(filepath);
// remove the project root from the filepath // remove the project root from the filepath
return filepath.replace(this->project->root + "/", ""); return filepath.replace(this->project->root + "/", "");
@ -107,21 +104,21 @@ poryjson::Json RegionMapPropertiesDialog::saveToJson() {
} }
void RegionMapPropertiesDialog::on_browse_tilesetImagePath_clicked() { void RegionMapPropertiesDialog::on_browse_tilesetImagePath_clicked() {
QString path = browse("Images (*.png *.bmp)", QFileDialog::ExistingFile); QString path = browse("Images (*.png *.bmp)");
if (!path.isEmpty()) { if (!path.isEmpty()) {
ui->config_tilemapImagePath->setText(path); ui->config_tilemapImagePath->setText(path);
} }
} }
void RegionMapPropertiesDialog::on_browse_tilemapBinPath_clicked() { 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()) { if (!path.isEmpty()) {
ui->config_tilemapBinPath->setText(path); ui->config_tilemapBinPath->setText(path);
} }
} }
void RegionMapPropertiesDialog::on_browse_tilemapPalettePath_clicked() { void RegionMapPropertiesDialog::on_browse_tilemapPalettePath_clicked() {
QString path = browse("Text (*.pal)", QFileDialog::AnyFile); QString path = browse("Text (*.pal)");
if (!path.isEmpty()) { if (!path.isEmpty()) {
ui->config_tilemapPalettePath->setText(path); ui->config_tilemapPalettePath->setText(path);
} }
@ -129,12 +126,12 @@ void RegionMapPropertiesDialog::on_browse_tilemapPalettePath_clicked() {
void RegionMapPropertiesDialog::on_browse_layoutPath_clicked() { void RegionMapPropertiesDialog::on_browse_layoutPath_clicked() {
if (ui->config_layoutFormat->currentIndex() == 0) { 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()) { if (!path.isEmpty()) {
ui->config_layoutPath->setText(path); ui->config_layoutPath->setText(path);
} }
} else { } else {
QString path = browse("Binary (*.bin)", QFileDialog::AnyFile); QString path = browse("Binary (*.bin)");
if (!path.isEmpty()) { if (!path.isEmpty()) {
ui->config_layoutPath->setText(path); ui->config_layoutPath->setText(path);
} }

View file

@ -7,7 +7,7 @@
#include "imageexport.h" #include "imageexport.h"
#include "config.h" #include "config.h"
#include "shortcut.h" #include "shortcut.h"
#include <QFileDialog> #include "filedialog.h"
#include <QMessageBox> #include <QMessageBox>
#include <QDialogButtonBox> #include <QDialogButtonBox>
#include <QCloseEvent> #include <QCloseEvent>
@ -637,15 +637,11 @@ void TilesetEditor::importTilesetTiles(Tileset *tileset, bool primary) {
QString descriptor = primary ? "primary" : "secondary"; QString descriptor = primary ? "primary" : "secondary";
QString descriptorCaps = primary ? "Primary" : "Secondary"; QString descriptorCaps = primary ? "Primary" : "Secondary";
QString filepath = QFileDialog::getOpenFileName( QString filepath = FileDialog::getOpenFileName(this, QString("Import %1 Tileset Tiles Image").arg(descriptorCaps), "", "Image Files (*.png *.bmp *.jpg *.dib)");
this,
QString("Import %1 Tileset Tiles Image").arg(descriptorCaps),
this->project->importExportPath,
"Image Files (*.png *.bmp *.jpg *.dib)");
if (filepath.isEmpty()) { if (filepath.isEmpty()) {
return; return;
} }
this->project->setImportExportPath(filepath);
logInfo(QString("Importing %1 tileset tiles '%2'").arg(descriptor).arg(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 // 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.setIcon(QMessageBox::Icon::Warning);
msgBox.exec(); msgBox.exec();
QString filepath = QFileDialog::getOpenFileName( QString filepath = FileDialog::getOpenFileName(this, "Select Palette for Tiles Image", "", "Palette Files (*.pal *.act *tpl *gpl)");
this,
QString("Select Palette for Tiles Image").arg(descriptorCaps),
this->project->importExportPath,
"Palette Files (*.pal *.act *tpl *gpl)");
if (filepath.isEmpty()) { if (filepath.isEmpty()) {
return; return;
} }
this->project->setImportExportPath(filepath);
bool error = false; bool error = false;
QList<QRgb> palette = PaletteUtil::parse(filepath, &error); QList<QRgb> palette = PaletteUtil::parse(filepath, &error);
if (error) { if (error) {
@ -939,10 +931,9 @@ void TilesetEditor::pasteMetatile(const Metatile * toPaste, QString newLabel)
void TilesetEditor::on_actionExport_Primary_Tiles_Image_triggered() void TilesetEditor::on_actionExport_Primary_Tiles_Image_triggered()
{ {
QString defaultName = QString("%1_Tiles_Pal%2").arg(this->primaryTileset->name).arg(this->paletteId); 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 defaultFilepath = QString("%1/%2.png").arg(FileDialog::getDirectory()).arg(defaultName);
QString filepath = QFileDialog::getSaveFileName(this, "Export Primary Tiles Image", defaultFilepath, "Image Files (*.png)"); QString filepath = FileDialog::getSaveFileName(this, "Export Primary Tiles Image", defaultFilepath, "Image Files (*.png)");
if (!filepath.isEmpty()) { if (!filepath.isEmpty()) {
this->project->setImportExportPath(filepath);
QImage image = this->tileSelector->buildPrimaryTilesIndexedImage(); QImage image = this->tileSelector->buildPrimaryTilesIndexedImage();
exportIndexed4BPPPng(image, filepath); exportIndexed4BPPPng(image, filepath);
} }
@ -951,10 +942,9 @@ void TilesetEditor::on_actionExport_Primary_Tiles_Image_triggered()
void TilesetEditor::on_actionExport_Secondary_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 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 defaultFilepath = QString("%1/%2.png").arg(FileDialog::getDirectory()).arg(defaultName);
QString filepath = QFileDialog::getSaveFileName(this, "Export Secondary Tiles Image", defaultFilepath, "Image Files (*.png)"); QString filepath = FileDialog::getSaveFileName(this, "Export Secondary Tiles Image", defaultFilepath, "Image Files (*.png)");
if (!filepath.isEmpty()) { if (!filepath.isEmpty()) {
this->project->setImportExportPath(filepath);
QImage image = this->tileSelector->buildSecondaryTilesIndexedImage(); QImage image = this->tileSelector->buildSecondaryTilesIndexedImage();
exportIndexed4BPPPng(image, filepath); exportIndexed4BPPPng(image, filepath);
} }
@ -963,10 +953,9 @@ void TilesetEditor::on_actionExport_Secondary_Tiles_Image_triggered()
void TilesetEditor::on_actionExport_Primary_Metatiles_Image_triggered() void TilesetEditor::on_actionExport_Primary_Metatiles_Image_triggered()
{ {
QString defaultName = QString("%1_Metatiles").arg(this->primaryTileset->name); QString defaultName = QString("%1_Metatiles").arg(this->primaryTileset->name);
QString defaultFilepath = QString("%1/%2.png").arg(this->project->importExportPath).arg(defaultName); QString defaultFilepath = QString("%1/%2.png").arg(FileDialog::getDirectory()).arg(defaultName);
QString filepath = QFileDialog::getSaveFileName(this, "Export Primary Metatiles Image", defaultFilepath, "Image Files (*.png)"); QString filepath = FileDialog::getSaveFileName(this, "Export Primary Metatiles Image", defaultFilepath, "Image Files (*.png)");
if (!filepath.isEmpty()) { if (!filepath.isEmpty()) {
this->project->setImportExportPath(filepath);
QImage image = this->metatileSelector->buildPrimaryMetatilesImage(); QImage image = this->metatileSelector->buildPrimaryMetatilesImage();
image.save(filepath, "PNG"); image.save(filepath, "PNG");
} }
@ -975,10 +964,9 @@ void TilesetEditor::on_actionExport_Primary_Metatiles_Image_triggered()
void TilesetEditor::on_actionExport_Secondary_Metatiles_Image_triggered() void TilesetEditor::on_actionExport_Secondary_Metatiles_Image_triggered()
{ {
QString defaultName = QString("%1_Metatiles").arg(this->secondaryTileset->name); QString defaultName = QString("%1_Metatiles").arg(this->secondaryTileset->name);
QString defaultFilepath = QString("%1/%2.png").arg(this->project->importExportPath).arg(defaultName); QString defaultFilepath = QString("%1/%2.png").arg(FileDialog::getDirectory()).arg(defaultName);
QString filepath = QFileDialog::getSaveFileName(this, "Export Secondary Metatiles Image", defaultFilepath, "Image Files (*.png)"); QString filepath = FileDialog::getSaveFileName(this, "Export Secondary Metatiles Image", defaultFilepath, "Image Files (*.png)");
if (!filepath.isEmpty()) { if (!filepath.isEmpty()) {
this->project->setImportExportPath(filepath);
QImage image = this->metatileSelector->buildSecondaryMetatilesImage(); QImage image = this->metatileSelector->buildSecondaryMetatilesImage();
image.save(filepath, "PNG"); image.save(filepath, "PNG");
} }
@ -998,15 +986,11 @@ void TilesetEditor::importTilesetMetatiles(Tileset *tileset, bool primary)
{ {
QString descriptorCaps = primary ? "Primary" : "Secondary"; QString descriptorCaps = primary ? "Primary" : "Secondary";
QString filepath = QFileDialog::getOpenFileName( QString filepath = FileDialog::getOpenFileName(this, QString("Import %1 Tileset Metatiles from Advance Map 1.92").arg(descriptorCaps), "", "Advance Map 1.92 Metatile Files (*.bvd)");
this,
QString("Import %1 Tileset Metatiles from Advance Map 1.92").arg(descriptorCaps),
this->project->importExportPath,
"Advance Map 1.92 Metatile Files (*.bvd)");
if (filepath.isEmpty()) { if (filepath.isEmpty()) {
return; return;
} }
this->project->setImportExportPath(filepath);
bool error = false; bool error = false;
QList<Metatile*> metatiles = MetatileParser::parse(filepath, &error, primary); QList<Metatile*> metatiles = MetatileParser::parse(filepath, &error, primary);
if (error) { if (error) {