mirror of https://github.com/PCSX2/pcsx2.git
Qt: Allow editing folder settings
This commit is contained in:
parent
a07ef0f5ee
commit
02d3c93c2c
|
@ -412,6 +412,17 @@ void EmuThread::reloadGameSettings()
|
|||
}
|
||||
}
|
||||
|
||||
void EmuThread::updateEmuFolders()
|
||||
{
|
||||
if (!isOnEmuThread())
|
||||
{
|
||||
QMetaObject::invokeMethod(this, &EmuThread::updateEmuFolders, Qt::QueuedConnection);
|
||||
return;
|
||||
}
|
||||
|
||||
Host::Internal::UpdateEmuFolders();
|
||||
}
|
||||
|
||||
void EmuThread::loadOurSettings()
|
||||
{
|
||||
m_verbose_status = Host::GetBaseBoolSettingValue("UI", "VerboseStatusBar", false);
|
||||
|
|
|
@ -70,6 +70,7 @@ public Q_SLOTS:
|
|||
void setSurfaceless(bool surfaceless);
|
||||
void applySettings();
|
||||
void reloadGameSettings();
|
||||
void updateEmuFolders();
|
||||
void toggleSoftwareRendering();
|
||||
void switchRenderer(GSRendererType renderer);
|
||||
void changeDisc(const QString& path);
|
||||
|
|
|
@ -228,14 +228,6 @@ void QtHost::SetDataDirectory()
|
|||
EmuFolders::DataRoot = EmuFolders::AppRoot;
|
||||
}
|
||||
|
||||
void QtHost::UpdateFolders()
|
||||
{
|
||||
// TODO: This should happen with the VM thread paused.
|
||||
auto lock = Host::GetSettingsLock();
|
||||
EmuFolders::LoadConfig(*s_base_settings_interface.get());
|
||||
EmuFolders::EnsureFoldersExist();
|
||||
}
|
||||
|
||||
bool QtHost::InitializeConfig()
|
||||
{
|
||||
if (!SetCriticalFolders())
|
||||
|
|
|
@ -40,8 +40,6 @@ namespace QtHost
|
|||
bool Initialize();
|
||||
void Shutdown();
|
||||
|
||||
void UpdateFolders();
|
||||
|
||||
/// Sets batch mode (exit after game shutdown).
|
||||
bool InBatchMode();
|
||||
void SetBatchMode(bool enabled);
|
||||
|
|
|
@ -20,17 +20,23 @@
|
|||
|
||||
#include <QtCore/QtCore>
|
||||
#include <QtGui/QAction>
|
||||
#include <QtWidgets/QAbstractButton>
|
||||
#include <QtWidgets/QCheckBox>
|
||||
#include <QtWidgets/QComboBox>
|
||||
#include <QtWidgets/QDoubleSpinBox>
|
||||
#include <QtWidgets/QFileDialog>
|
||||
#include <QtWidgets/QLineEdit>
|
||||
#include <QtWidgets/QSlider>
|
||||
#include <QtWidgets/QSpinBox>
|
||||
|
||||
#include "common/Path.h"
|
||||
|
||||
#include "pcsx2/Config.h"
|
||||
#include "pcsx2/HostSettings.h"
|
||||
|
||||
#include "EmuThread.h"
|
||||
#include "QtHost.h"
|
||||
#include "QtUtils.h"
|
||||
#include "Settings/SettingsDialog.h"
|
||||
|
||||
namespace SettingWidgetBinder
|
||||
|
@ -228,7 +234,7 @@ namespace SettingWidgetBinder
|
|||
static std::optional<QString> getNullableStringValue(const QCheckBox* widget)
|
||||
{
|
||||
return (widget->checkState() == Qt::PartiallyChecked) ?
|
||||
std::nullopt :
|
||||
std::nullopt :
|
||||
std::optional<QString>(widget->isChecked() ? QStringLiteral("1") : QStringLiteral("0"));
|
||||
}
|
||||
static void setNullableStringValue(QCheckBox* widget, std::optional<QString> value)
|
||||
|
@ -769,4 +775,70 @@ namespace SettingWidgetBinder
|
|||
}
|
||||
}
|
||||
|
||||
template <typename WidgetType>
|
||||
static void BindWidgetToFolderSetting(SettingsInterface* sif, WidgetType* widget,
|
||||
QAbstractButton* browse_button, QAbstractButton* open_button, QAbstractButton* reset_button,
|
||||
std::string section, std::string key, std::string default_value)
|
||||
{
|
||||
using Accessor = SettingAccessor<WidgetType>;
|
||||
|
||||
std::string current_path(Host::GetBaseStringSettingValue(section.c_str(), key.c_str(), default_value.c_str()));
|
||||
if (!Path::IsAbsolute(current_path))
|
||||
current_path = Path::Combine(EmuFolders::DataRoot, current_path);
|
||||
|
||||
const QString value(QString::fromStdString(current_path));
|
||||
Accessor::setStringValue(widget, value);
|
||||
|
||||
// if we're doing per-game settings, disable the widget, we only allow folder changes in the base config
|
||||
if (sif)
|
||||
{
|
||||
widget->setEnabled(false);
|
||||
if (browse_button)
|
||||
browse_button->setEnabled(false);
|
||||
if (reset_button)
|
||||
reset_button->setEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
Accessor::connectValueChanged(widget, [widget, section = std::move(section), key = std::move(key)]() {
|
||||
const std::string new_value(Accessor::getStringValue(widget).toStdString());
|
||||
if (!new_value.empty())
|
||||
{
|
||||
std::string relative_path(Path::MakeRelative(new_value, EmuFolders::DataRoot));
|
||||
QtHost::SetBaseStringSettingValue(section.c_str(), key.c_str(), relative_path.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
QtHost::RemoveBaseSettingValue(section.c_str(), key.c_str());
|
||||
}
|
||||
|
||||
g_emu_thread->updateEmuFolders();
|
||||
});
|
||||
|
||||
if (browse_button)
|
||||
{
|
||||
QObject::connect(browse_button, &QAbstractButton::clicked, browse_button, [widget, key]() {
|
||||
const QString path(QDir::toNativeSeparators(QFileDialog::getExistingDirectory(QtUtils::GetRootWidget(widget),
|
||||
qApp->translate("SettingWidgetBinder", "Select folder for %1").arg(QString::fromStdString(key)))));
|
||||
if (path.isEmpty())
|
||||
return;
|
||||
|
||||
Accessor::setStringValue(widget, path);
|
||||
});
|
||||
}
|
||||
if (open_button)
|
||||
{
|
||||
QObject::connect(open_button, &QAbstractButton::clicked, open_button, [widget]() {
|
||||
QString path(Accessor::getStringValue(widget));
|
||||
if (!path.isEmpty())
|
||||
QtUtils::OpenURL(QtUtils::GetRootWidget(widget), QUrl::fromLocalFile(path));
|
||||
});
|
||||
}
|
||||
if (reset_button)
|
||||
{
|
||||
QObject::connect(reset_button, &QAbstractButton::clicked, reset_button, [widget, default_value = std::move(default_value)]() {
|
||||
Accessor::setStringValue(widget, QString::fromStdString(Path::Combine(EmuFolders::AppRoot, default_value)));
|
||||
});
|
||||
}
|
||||
}
|
||||
} // namespace SettingWidgetBinder
|
||||
|
|
|
@ -38,28 +38,17 @@ BIOSSettingsWidget::BIOSSettingsWidget(SettingsDialog* dialog, QWidget* parent)
|
|||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.fastBoot, "EmuCore", "EnableFastBoot", true);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.patchRegion, "EmuCore", "PatchBios", false);
|
||||
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.regionComboBox, "EmuCore", "PatchRegion", BiosZoneStrings, BiosZoneBytes, BiosZoneBytes[0]);
|
||||
SettingWidgetBinder::BindWidgetToFolderSetting(sif, m_ui.searchDirectory, m_ui.browseSearchDirectory, m_ui.openSearchDirectory,
|
||||
m_ui.resetSearchDirectory, "Folders", "Bios", "bios");
|
||||
|
||||
dialog->registerWidgetHelp(m_ui.patchRegion, tr("Patch Region"),tr("Unchecked"),
|
||||
dialog->registerWidgetHelp(m_ui.patchRegion, tr("Patch Region"), tr("Unchecked"),
|
||||
tr("Patches the BIOS region byte in ROM. Not recommended unless you really know what you're doing."));
|
||||
dialog->registerWidgetHelp(m_ui.fastBoot, tr("Fast Boot"), tr("Unchecked"),
|
||||
tr("Patches the BIOS to skip the console's boot animation."));
|
||||
|
||||
updateSearchDirectory();
|
||||
refreshList();
|
||||
|
||||
connect(m_ui.searchDirectory, &QLineEdit::textChanged, [this](const QString& text) {
|
||||
QtHost::SetBaseStringSettingValue("Folders", "Bios", text.toUtf8().constData());
|
||||
QtHost::UpdateFolders();
|
||||
refreshList();
|
||||
});
|
||||
connect(m_ui.resetSearchDirectory, &QPushButton::clicked, [this]() {
|
||||
QtHost::RemoveBaseSettingValue("Folders", "Bios");
|
||||
QtHost::UpdateFolders();
|
||||
updateSearchDirectory();
|
||||
refreshList();
|
||||
});
|
||||
connect(m_ui.browseSearchDirectory, &QPushButton::clicked, this, &BIOSSettingsWidget::browseSearchDirectory);
|
||||
connect(m_ui.openSearchDirectory, &QPushButton::clicked, this, &BIOSSettingsWidget::openSearchDirectory);
|
||||
connect(m_ui.searchDirectory, &QLineEdit::textChanged, this, &BIOSSettingsWidget::refreshList);
|
||||
connect(m_ui.refresh, &QPushButton::clicked, this, &BIOSSettingsWidget::refreshList);
|
||||
connect(m_ui.fileList, &QTreeWidget::currentItemChanged, this, &BIOSSettingsWidget::listItemChanged);
|
||||
|
||||
|
@ -89,27 +78,6 @@ void BIOSSettingsWidget::refreshList()
|
|||
m_refresh_thread->start();
|
||||
}
|
||||
|
||||
void BIOSSettingsWidget::browseSearchDirectory()
|
||||
{
|
||||
QString directory = QDir::toNativeSeparators(QFileDialog::getExistingDirectory(
|
||||
QtUtils::GetRootWidget(this), tr("Select Directory"), m_ui.searchDirectory->text()));
|
||||
if (directory.isEmpty())
|
||||
return;
|
||||
|
||||
m_ui.searchDirectory->setText(directory);
|
||||
}
|
||||
|
||||
void BIOSSettingsWidget::openSearchDirectory()
|
||||
{
|
||||
QtUtils::OpenURL(this, QUrl::fromLocalFile(m_ui.searchDirectory->text()));
|
||||
}
|
||||
|
||||
void BIOSSettingsWidget::updateSearchDirectory()
|
||||
{
|
||||
// this will generate a full path
|
||||
m_ui.searchDirectory->setText(QString::fromStdString(EmuFolders::Bios));
|
||||
}
|
||||
|
||||
void BIOSSettingsWidget::listRefreshed(const QVector<BIOSInfo>& items)
|
||||
{
|
||||
const std::string selected_bios(Host::GetBaseStringSettingValue("Filenames", "BIOS"));
|
||||
|
|
|
@ -47,9 +47,6 @@ public:
|
|||
|
||||
private Q_SLOTS:
|
||||
void refreshList();
|
||||
void browseSearchDirectory();
|
||||
void openSearchDirectory();
|
||||
void updateSearchDirectory();
|
||||
|
||||
void listItemChanged(const QTreeWidgetItem* current, const QTreeWidgetItem* previous);
|
||||
void listRefreshed(const QVector<BIOSInfo>& items);
|
||||
|
|
|
@ -188,7 +188,7 @@
|
|||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="resources/resources.qrc"/>
|
||||
<include location="../resources/resources.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
|
|
@ -15,9 +15,14 @@
|
|||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "common/Assertions.h"
|
||||
#include "Frontend/LayeredSettingsInterface.h"
|
||||
#include "GS.h"
|
||||
#include "GS/Renderers/HW/GSTextureReplacements.h"
|
||||
#include "Host.h"
|
||||
#include "HostSettings.h"
|
||||
#include "Frontend/LayeredSettingsInterface.h"
|
||||
#include "MemoryCardFile.h"
|
||||
#include "Sio.h"
|
||||
#include "VMManager.h"
|
||||
|
||||
static std::mutex s_settings_mutex;
|
||||
static LayeredSettingsInterface s_layered_settings_interface;
|
||||
|
@ -202,3 +207,45 @@ void Host::Internal::SetInputSettingsLayer(SettingsInterface* sif)
|
|||
std::unique_lock lock(s_settings_mutex);
|
||||
s_layered_settings_interface.SetLayer(LayeredSettingsInterface::LAYER_INPUT, sif);
|
||||
}
|
||||
|
||||
void Host::Internal::UpdateEmuFolders()
|
||||
{
|
||||
const std::string old_cheats_directory(EmuFolders::Cheats);
|
||||
const std::string old_cheats_ws_directory(EmuFolders::CheatsWS);
|
||||
const std::string old_cheats_ni_directory(EmuFolders::CheatsNI);
|
||||
const std::string old_memcards_directory(EmuFolders::MemoryCards);
|
||||
const std::string old_textures_directory(EmuFolders::Textures);
|
||||
|
||||
EmuFolders::LoadConfig(*GetBaseSettingsLayer());
|
||||
EmuFolders::EnsureFoldersExist();
|
||||
|
||||
if (VMManager::HasValidVM())
|
||||
{
|
||||
if (EmuFolders::Cheats != old_cheats_directory ||
|
||||
EmuFolders::CheatsWS != old_cheats_ws_directory ||
|
||||
EmuFolders::CheatsNI != old_cheats_ni_directory)
|
||||
{
|
||||
VMManager::ReloadPatches(true, true);
|
||||
}
|
||||
|
||||
if (EmuFolders::MemoryCards != old_memcards_directory)
|
||||
{
|
||||
FileMcd_EmuClose();
|
||||
FileMcd_EmuOpen();
|
||||
|
||||
for (u32 port = 0; port < 2; port++)
|
||||
{
|
||||
for (u32 slot = 0; slot < 4; slot++)
|
||||
SetForceMcdEjectTimeoutNow(port, slot);
|
||||
}
|
||||
}
|
||||
|
||||
if (EmuFolders::Textures != old_textures_directory)
|
||||
{
|
||||
GetMTGS().RunOnGSThread([]() {
|
||||
if (VMManager::HasValidVM())
|
||||
GSTextureReplacements::ReloadReplacementMap();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,5 +79,8 @@ namespace Host
|
|||
|
||||
/// Sets the input profile settings layer. Called by VMManager when the game changes.
|
||||
void SetInputSettingsLayer(SettingsInterface* sif);
|
||||
|
||||
/// Updates the variables in the EmuFolders namespace, reloading subsystems if needed. Must call with the lock held.
|
||||
void UpdateEmuFolders();
|
||||
} // namespace Internal
|
||||
} // namespace Host
|
Loading…
Reference in New Issue