Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FEXQonfig: Fix minor saving/loading quirks #4035

Merged
merged 6 commits into from
Sep 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion Source/Tools/FEXQonfig/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,8 @@ static void ConfigInit(fextl::string ConfigFilename) {

// Ensure config and RootFS directories exist
std::error_code ec {};
fextl::string Dirs[] = {FHU::Filesystem::ParentPath(ConfigFilename), FEXCore::Config::GetDataDirectory() + "RootFS/"};
std::filesystem::path Dirs[] = {std::filesystem::absolute(ConfigFilename).parent_path(),
std::filesystem::absolute(FEXCore::Config::GetDataDirectory()) / "RootFS/"};
for (auto& Dir : Dirs) {
bool created = std::filesystem::create_directories(Dir, ec);
if (created) {
Expand Down Expand Up @@ -316,7 +317,9 @@ ConfigRuntime::ConfigRuntime(const QString& ConfigFilename) {
if (!ConfigFilename.isEmpty()) {
Window->setProperty("configFilename", QUrl::fromLocalFile(ConfigFilename));
} else {
Window->setProperty("configFilename", QUrl::fromLocalFile(FEXCore::Config::GetConfigFileLocation().c_str()));
Window->setProperty("configDirty", true);
Window->setProperty("loadedDefaults", true);
}

ConfigRuntime::connect(Window, SIGNAL(selectedConfigFile(const QUrl&)), this, SLOT(onLoad(const QUrl&)));
Expand Down
40 changes: 29 additions & 11 deletions Source/Tools/FEXQonfig/main.qml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ ApplicationWindow {
property url configFilename

property bool configDirty: false
property bool loadedDefaults: false
property bool closeConfirmed: false

signal selectedConfigFile(name: url)
Expand All @@ -31,6 +32,13 @@ ApplicationWindow {
// Property used to force reloading any elements that read ConfigModel
property bool refreshCache: false

onConfigDirtyChanged: {
if (!configDirty) {
// We either just saved or loaded a file
loadedDefaults = false
}
}

function refreshUI() {
refreshCache = !refreshCache
}
Expand All @@ -40,36 +48,46 @@ ApplicationWindow {
if (str.startsWith("file://")) {
return decodeURIComponent(str.substring(7))
}
if (str.startsWith("file:")) {
return decodeURIComponent(str.substring(5))
}

return str;
}

FileDialog {
id: openFileDialog
title: qsTr("Open FEX configuration")
property bool isSaving: false

title: isSaving ? qsTr("Save FEX configuration") : qsTr("Open FEX configuration")
nameFilters: [ qsTr("Config files(*.json)"), qsTr("All files(*)") ]

selectExisting: !isSaving

property var onNextAccept: null

// Prompts the user for an existing file and calls the callback on completion
function openAndThen(callback) {
this.selectExisting = true
function loadAndThen(callback) {
isSaving = false
console.assert(!onNextAccept, "Tried to open dialog multiple times")
onNextAccept = callback
open()
}

// Prompts the user for a new or existing file and calls the callback on completion
function openNewAndThen(callback) {
this.selectExisting = false
function saveAndThen(callback) {
isSaving = true
console.assert(!onNextAccept, "Tried to open dialog multiple times")
onNextAccept = callback
open()
}

onAccepted: {
root.selectedConfigFile(selectedFile)
if (!isSaving) {
root.selectedConfigFile(selectedFile)
}
configFilename = selectedFile
configDirty = false
if (onNextAccept) {
onNextAccept()
onNextAccept = null
Expand All @@ -90,7 +108,7 @@ ApplicationWindow {
case buttonSave:
if (configFilename.toString() === "") {
// Filename not yet set => trigger "Save As" dialog
openFileDialog.openNewAndThen(() => {
openFileDialog.saveAndThen(() => {
save(configFilename)
root.close()
});
Expand Down Expand Up @@ -122,7 +140,7 @@ ApplicationWindow {

if (filename.toString() === "") {
// Filename not yet set => trigger "Save As" dialog
openFileDialog.openNewAndThen(() => {
openFileDialog.saveAndThen(() => {
save(configFilename)
});
return
Expand All @@ -139,7 +157,7 @@ ApplicationWindow {
text: qsTr("&Open...")
shortcut: StandardKey.Open
// TODO: Ask to discard pending changes first
onTriggered: openFileDialog.openAndThen(() => {})
onTriggered: openFileDialog.loadAndThen(() => {})
}
Action {
text: qsTr("&Save")
Expand All @@ -150,7 +168,7 @@ ApplicationWindow {
text: qsTr("Save &as...")
shortcut: StandardKey.SaveAs
onTriggered: {
openFileDialog.openNewAndThen(() => {
openFileDialog.saveAndThen(() => {
root.save(configFilename)
});
}
Expand Down Expand Up @@ -898,7 +916,7 @@ ApplicationWindow {
Label {
Layout.alignment: Qt.AlignHCenter
enabled: false
text: configFilename.toString() === ""
text: loadedDefaults
? qsTr("Config.json not found — loaded defaults")
: qsTr("Editing %1").arg(urlToLocalFile(configFilename))
}
Expand Down
Loading