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
16 changed files with 161 additions and 91 deletions

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 "imageexport.h"
#include "newmapconnectiondialog.h"
#include "filedialog.h"
#include <QFileDialog>
#include <QClipboard>
#include <QDirIterator>
#include <QStandardItemModel>
@@ -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);

View File

@@ -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.

View File

@@ -4,9 +4,9 @@
#include "config.h"
#include "editor.h"
#include "shortcut.h"
#include "filedialog.h"
#include <QDir>
#include <QFileDialog>
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);
}

View File

@@ -2,8 +2,8 @@
#include "ui_mapimageexporter.h"
#include "qgifimage.h"
#include "editcommands.h"
#include "filedialog.h"
#include <QFileDialog>
#include <QImage>
#include <QPainter>
#include <QPoint>
@@ -98,13 +98,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:
case ImageExporterMode::Stitch:

View File

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

View File

@@ -3,8 +3,8 @@
#include "paletteutil.h"
#include "config.h"
#include "log.h"
#include "filedialog.h"
#include <QFileDialog>
#include <QMessageBox>
@@ -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<QRgb> palette = PaletteUtil::parse(filepath, &error);
if (error) {

View File

@@ -2,6 +2,7 @@
#include "config.h"
#include "noscrollcombobox.h"
#include "prefab.h"
#include "filedialog.h"
#include <QAbstractButton>
#include <QFormLayout>
@@ -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));

View File

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

View File

@@ -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);
}

View File

@@ -7,7 +7,7 @@
#include "imageexport.h"
#include "config.h"
#include "shortcut.h"
#include <QFileDialog>
#include "filedialog.h"
#include <QMessageBox>
#include <QDialogButtonBox>
#include <QCloseEvent>
@@ -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<QRgb> 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<Metatile*> metatiles = MetatileParser::parse(filepath, &error, primary);
if (error) {