return winUaeQtFileDialogInitialSavePath(path, fallbackName);
}
+static QFileDialog::Options pathSelectionDialogOptions()
+{
+ QFileDialog::Options options = QFileDialog::DontResolveSymlinks;
+#if defined(__APPLE__)
+ // The native macOS panel returns the resolved target for symlinked files.
+ options |= QFileDialog::DontUseNativeDialog;
+#endif
+ return options;
+}
+
+static QString getOpenFileNamePreservingSymlinks(QWidget *parent,
+ const QString &caption, const QString &dir, const QString &filter)
+{
+ return QFileDialog::getOpenFileName(parent, caption, dir, filter, nullptr,
+ pathSelectionDialogOptions());
+}
+
+static QString getExistingDirectoryPreservingSymlinks(QWidget *parent,
+ const QString &caption, const QString &dir)
+{
+ return QFileDialog::getExistingDirectory(parent, caption, dir,
+ pathSelectionDialogOptions() | QFileDialog::ShowDirsOnly);
+}
+
static void addBrowse(QComboBox *field, QWidget *parent, const QString &caption, const QString &filter)
{
- const QString path = QFileDialog::getOpenFileName(parent, caption, fileDialogInitialPath(field->currentText()), filter);
+ const QString path = getOpenFileNamePreservingSymlinks(parent, caption, fileDialogInitialPath(field->currentText()), filter);
if (!path.isEmpty()) {
setPathComboText(field, path);
}
connect(customRomEnd, &QLineEdit::textChanged, this, [this](const QString &) { storeCurrentCustomRomBoard(); });
connect(customRomFile, &QLineEdit::textChanged, this, [this](const QString &) { storeCurrentCustomRomBoard(); });
connect(customRomBrowse, &QPushButton::clicked, this, [this]() {
- const QString selected = QFileDialog::getOpenFileName(this, QStringLiteral("Select custom ROM file"), fileDialogInitialPath(customRomFile->text()), QStringLiteral("ROM files (*.rom *.bin);;All files (*)"));
+ const QString selected = getOpenFileNamePreservingSymlinks(this, QStringLiteral("Select custom ROM file"), fileDialogInitialPath(customRomFile->text()), QStringLiteral("ROM files (*.rom *.bin);;All files (*)"));
if (selected.isEmpty()) {
return;
}
void browseDiskSwapperImage(int slot)
{
- const QString selected = QFileDialog::getOpenFileName(this, QStringLiteral("Select floppy image"), fileDialogInitialPath(diskSwapperPathAt(slot)), floppyDiskImageFilter());
+ const QString selected = getOpenFileNamePreservingSymlinks(this, QStringLiteral("Select floppy image"), fileDialogInitialPath(diskSwapperPathAt(slot)), floppyDiskImageFilter());
if (!selected.isEmpty()) {
setPathComboText(diskSwapperPath, selected);
setDiskSwapperPath(slot, selected);
});
connect(selectCdImage, &QPushButton::clicked, this, [this]() {
const QString initialPath = fileDialogInitialPath(cdSlotPath->currentText());
- const QString selected = QFileDialog::getOpenFileName(this, QStringLiteral("Select CD image"), initialPath, cdImageFilter());
+ const QString selected = getOpenFileNamePreservingSymlinks(this, QStringLiteral("Select CD image"), initialPath, cdImageFilter());
if (!selected.isEmpty()) {
setPathComboText(cdSlotPath, selected);
setComboTextIfChanged(cdSlotType, QStringLiteral("Image file"));
if (hasStateRecorder) {
connect(statePlay, &QCheckBox::clicked, this, [this, statePlay, updateStateRecorderControls](bool checked) {
if (checked) {
- const QString selected = QFileDialog::getOpenFileName(
+ const QString selected = getOpenFileNamePreservingSymlinks(
this,
QStringLiteral("Select input recording"),
expandedPathText(unixDefaultDataSubPath(QStringLiteral("Save States"))),
root->addLayout(right, 1);
const auto selectStateFile = [this]() {
- const QString selected = QFileDialog::getOpenFileName(this, QStringLiteral("Select state file"), fileDialogInitialPath(stateFileName->currentText()), QStringLiteral("WinUAE state files (*.uss);;All files (*)"));
+ const QString selected = getOpenFileNamePreservingSymlinks(this, QStringLiteral("Select state file"), fileDialogInitialPath(stateFileName->currentText()), QStringLiteral("WinUAE state files (*.uss);;All files (*)"));
if (!selected.isEmpty()) {
setPathComboText(stateFileName, selected);
stateFileClear->setChecked(false);
: fileDialogInitialPath(field->text());
QString path;
if (directory) {
- path = QFileDialog::getExistingDirectory(this, caption, initialPath);
+ path = getExistingDirectoryPreservingSymlinks(this, caption, initialPath);
} else {
- path = QFileDialog::getOpenFileName(this, caption, initialPath, QStringLiteral("All files (*)"));
+ path = getOpenFileNamePreservingSymlinks(this, caption, initialPath, QStringLiteral("All files (*)"));
}
if (!path.isEmpty()) {
field->setText(path);
void addHardfileMountDialog()
{
- const QString path = QFileDialog::getOpenFileName(this, QStringLiteral("Add hardfile"), fileDialogInitialPath(QString()), hardfileImageFilter());
+ const QString path = getOpenFileNamePreservingSymlinks(this, QStringLiteral("Add hardfile"), fileDialogInitialPath(QString()), hardfileImageFilter());
if (path.isEmpty()) {
return;
}
connect(selectDirectory, &QPushButton::clicked, this, [this, path, volume, readOnly, updateReadOnlyForPath]() {
const QString initialPath = fileDialogInitialDirectory(path->text());
- const QString selected = QFileDialog::getExistingDirectory(this, QStringLiteral("Select directory"), initialPath);
+ const QString selected = getExistingDirectoryPreservingSymlinks(this, QStringLiteral("Select directory"), initialPath);
if (!selected.isEmpty()) {
path->setText(selected);
if (volume->text().isEmpty()) {
if (selectArchive) {
connect(selectArchive, &QPushButton::clicked, this, [this, path, volume, updateReadOnlyForPath]() {
const QString initialPath = fileDialogInitialPath(path->text());
- const QString selected = QFileDialog::getOpenFileName(this, QStringLiteral("Select directory archive"), initialPath, directoryArchiveFilter());
+ const QString selected = getOpenFileNamePreservingSymlinks(this, QStringLiteral("Select directory archive"), initialPath, directoryArchiveFilter());
if (!selected.isEmpty()) {
path->setText(selected);
if (volume->text().isEmpty()) {
connect(browse, &QPushButton::clicked, this, [this, path]() {
const QString initialPath = fileDialogInitialPath(path->text());
- const QString selected = QFileDialog::getOpenFileName(this, QStringLiteral("Select hardfile"), initialPath, hardfileImageFilter());
+ const QString selected = getOpenFileNamePreservingSymlinks(this, QStringLiteral("Select hardfile"), initialPath, hardfileImageFilter());
if (!selected.isEmpty()) {
path->setText(selected);
}
});
connect(geometryBrowse, &QPushButton::clicked, this, [this, geometryFile]() {
const QString initialPath = fileDialogInitialPath(geometryFile->text());
- const QString selected = QFileDialog::getOpenFileName(this, QStringLiteral("Select geometry file"), initialPath, QStringLiteral("Geometry files (*.geo);;All files (*)"));
+ const QString selected = getOpenFileNamePreservingSymlinks(this, QStringLiteral("Select geometry file"), initialPath, QStringLiteral("Geometry files (*.geo);;All files (*)"));
if (!selected.isEmpty()) {
geometryFile->setText(selected);
}
});
connect(filesysBrowse, &QPushButton::clicked, this, [this, filesys]() {
const QString initialPath = fileDialogInitialPath(filesys->text());
- const QString selected = QFileDialog::getOpenFileName(this, QStringLiteral("Select filesystem"), initialPath, QStringLiteral("Filesystem files (*.fs *.filesystem);;All files (*)"));
+ const QString selected = getOpenFileNamePreservingSymlinks(this, QStringLiteral("Select filesystem"), initialPath, QStringLiteral("Filesystem files (*.fs *.filesystem);;All files (*)"));
if (!selected.isEmpty()) {
filesys->setText(selected);
}
connect(selectFile, &QPushButton::clicked, this, [this, path]() {
const QString initialPath = fileDialogInitialPath(path->text());
- const QString selected = QFileDialog::getOpenFileName(this, QStringLiteral("Select tape image"), initialPath, QStringLiteral("Tape images (*.tap *.raw);;All files (*)"));
+ const QString selected = getOpenFileNamePreservingSymlinks(this, QStringLiteral("Select tape image"), initialPath, QStringLiteral("Tape images (*.tap *.raw);;All files (*)"));
if (!selected.isEmpty()) {
path->setText(selected);
}
});
connect(selectDirectory, &QPushButton::clicked, this, [this, path]() {
const QString initialPath = fileDialogInitialDirectory(path->text());
- const QString selected = QFileDialog::getExistingDirectory(this, QStringLiteral("Select tape directory"), initialPath);
+ const QString selected = getExistingDirectoryPreservingSymlinks(this, QStringLiteral("Select tape directory"), initialPath);
if (!selected.isEmpty()) {
path->setText(selected);
}
void loadConfigDialog()
{
- const QString path = QFileDialog::getOpenFileName(this, QStringLiteral("Load configuration"), configurationDirectory(), QStringLiteral("WinUAE configuration (*.uae);;All files (*)"));
+ const QString path = getOpenFileNamePreservingSymlinks(this, QStringLiteral("Load configuration"), configurationDirectory(), QStringLiteral("WinUAE configuration (*.uae);;All files (*)"));
if (!path.isEmpty()) {
loadConfig(path);
}
QString selected;
if (shortcut >= 0 && shortcut < 4) {
- selected = QFileDialog::getOpenFileName(
+ selected = getOpenFileNamePreservingSymlinks(
nullptr,
QStringLiteral("Select disk image for DF%1:").arg(shortcut),
runtimeDialogDirectory(initialPath),
amigaDiskImageFilter());
} else if (shortcut == 4) {
- selected = QFileDialog::getOpenFileName(
+ selected = getOpenFileNamePreservingSymlinks(
nullptr,
QStringLiteral("Restore state"),
runtimeDialogDirectory(initialPath),
selected += QStringLiteral(".uss");
}
} else if (shortcut == 6) {
- selected = QFileDialog::getOpenFileName(
+ selected = getOpenFileNamePreservingSymlinks(
nullptr,
QStringLiteral("Select CD image"),
runtimeDialogDirectory(initialPath),