Qt: Defer folder update until editing complete

Closes #7215.
This commit is contained in:
Stenzek 2023-09-09 14:42:40 +10:00 committed by Connor McLaughlin
parent f5684c43dd
commit d9587e20c0
1 changed files with 54 additions and 28 deletions

View File

@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@ -29,9 +29,11 @@
#include <QtWidgets/QLabel>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QMenu>
#include <QtWidgets/QMessageBox>
#include <QtWidgets/QSlider>
#include <QtWidgets/QSpinBox>
#include "common/FileSystem.h"
#include "common/Path.h"
#include "pcsx2/Config.h"
@ -125,9 +127,11 @@ namespace SettingWidgetBinder
static void makeNullableBool(QComboBox* widget, bool globalValue)
{
//: THIS STRING IS SHARED ACROSS MULTIPLE OPTIONS. Be wary about gender/number. Also, ignore Crowdin's warning regarding [Enabled]: the text must be translated.
widget->insertItem(0, globalValue ? qApp->translate("SettingsDialog", "Use Global Setting [Enabled]") :
//: THIS STRING IS SHARED ACROSS MULTIPLE OPTIONS. Be wary about gender/number. Also, ignore Crowdin's warning regarding [Disabled]: the text must be translated.
qApp->translate("SettingsDialog", "Use Global Setting [Disabled]"));
widget->insertItem(0,
globalValue ?
qApp->translate("SettingsDialog", "Use Global Setting [Enabled]") :
//: THIS STRING IS SHARED ACROSS MULTIPLE OPTIONS. Be wary about gender/number. Also, ignore Crowdin's warning regarding [Disabled]: the text must be translated.
qApp->translate("SettingsDialog", "Use Global Setting [Disabled]"));
}
static int getIntValue(const QComboBox* widget) { return widget->currentIndex(); }
@ -939,9 +943,7 @@ namespace SettingWidgetBinder
for (int i = 0; enum_names[i] != nullptr; i++)
{
widget->addItem(translation_ctx ?
qApp->translate(translation_ctx, enum_names[i]) :
QString::fromUtf8(enum_names[i]));
widget->addItem(translation_ctx ? qApp->translate(translation_ctx, enum_names[i]) : QString::fromUtf8(enum_names[i]));
}
int enum_index = -1;
@ -997,12 +999,11 @@ namespace SettingWidgetBinder
}
}
template <typename WidgetType>
static inline void BindWidgetToFolderSetting(SettingsInterface* sif, WidgetType* widget, QAbstractButton* browse_button,
static inline void BindWidgetToFolderSetting(SettingsInterface* sif, QLineEdit* widget, QAbstractButton* browse_button,
QAbstractButton* open_button, QAbstractButton* reset_button, std::string section, std::string key, std::string default_value,
bool use_relative = true)
{
using Accessor = SettingAccessor<WidgetType>;
using Accessor = SettingAccessor<QLineEdit>;
std::string current_path(Host::GetBaseStringSettingValue(section.c_str(), key.c_str(), default_value.c_str()));
if (current_path.empty())
@ -1024,39 +1025,60 @@ namespace SettingWidgetBinder
return;
}
Accessor::connectValueChanged(widget, [widget, section = std::move(section), key = std::move(key), use_relative]() {
const std::string new_value(Accessor::getStringValue(widget).toStdString());
auto value_changed = [widget, section = std::move(section), key = std::move(key), default_value, use_relative]() {
const std::string new_value(widget->text().toStdString());
if (!new_value.empty())
{
if (use_relative)
if (FileSystem::DirectoryExists(new_value.c_str()) ||
QMessageBox::question(QtUtils::GetRootWidget(widget), qApp->translate("SettingWidgetBinder", "Confirm Folder"),
qApp->translate("SettingWidgetBinder",
"The chosen directory does not currently exist:\n\n%1\n\nDo you want to create this directory?")
.arg(QString::fromStdString(new_value)),
QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes)
{
const std::string relative_path(Path::MakeRelative(new_value, EmuFolders::DataRoot));
Host::SetBaseStringSettingValue(section.c_str(), key.c_str(), relative_path.c_str());
}
else
{
Host::SetBaseStringSettingValue(section.c_str(), key.c_str(), new_value.c_str());
if (use_relative)
{
const std::string relative_path(Path::MakeRelative(new_value, EmuFolders::DataRoot));
Host::SetBaseStringSettingValue(section.c_str(), key.c_str(), relative_path.c_str());
}
else
{
Host::SetBaseStringSettingValue(section.c_str(), key.c_str(), new_value.c_str());
}
Host::CommitBaseSettingChanges();
g_emu_thread->updateEmuFolders();
return;
}
}
else
{
Host::RemoveBaseSettingValue(section.c_str(), key.c_str());
QMessageBox::critical(QtUtils::GetRootWidget(widget), qApp->translate("SettingWidgetBinder", "Error"),
qApp->translate("SettingWidgetBinder", "Folder path cannot be empty."));
}
Host::CommitBaseSettingChanges();
g_emu_thread->updateEmuFolders();
});
// reset to old value
std::string current_path(Host::GetBaseStringSettingValue(section.c_str(), key.c_str(), default_value.c_str()));
if (current_path.empty())
current_path = default_value;
else if (use_relative && !Path::IsAbsolute(current_path))
current_path = Path::Canonicalize(Path::Combine(EmuFolders::DataRoot, current_path));
widget->setText(QString::fromStdString(current_path));
};
if (browse_button)
{
QObject::connect(browse_button, &QAbstractButton::clicked, browse_button, [widget, key]() {
QObject::connect(browse_button, &QAbstractButton::clicked, browse_button, [widget, key, value_changed]() {
const QString path(QDir::toNativeSeparators(QFileDialog::getExistingDirectory(QtUtils::GetRootWidget(widget),
//It seems that the latter half should show the types of folders that can be selected within Settings -> Folders, but right now it's broken. It would be best for localization purposes to duplicate this into multiple lines, each per type of folder.
qApp->translate("SettingWidgetBinder", "Select folder for %1").arg(QString::fromStdString(key)))));
if (path.isEmpty())
return;
Accessor::setStringValue(widget, path);
widget->setText(path);
value_changed();
});
}
if (open_button)
@ -1069,10 +1091,14 @@ namespace SettingWidgetBinder
}
if (reset_button)
{
QObject::connect(reset_button, &QAbstractButton::clicked, reset_button, [widget, default_value = std::move(default_value)]() {
Accessor::setStringValue(widget, QString::fromStdString(default_value));
});
QObject::connect(
reset_button, &QAbstractButton::clicked, reset_button, [widget, default_value = std::move(default_value), value_changed]() {
widget->setText(QString::fromStdString(default_value));
value_changed();
});
}
widget->connect(widget, &QLineEdit::editingFinished, widget, std::move(value_changed));
}
static inline void BindSliderToIntSetting(SettingsInterface* sif, QSlider* slider, QLabel* label, const QString& label_suffix,