mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-08-13 11:39:09 +00:00
Merge 33c9aa714b
into 72ef27c157
This commit is contained in:
commit
af590db18f
6 changed files with 118 additions and 95 deletions
|
@ -364,8 +364,8 @@ add_executable(dolphin-emu
|
|||
Settings/InterfacePane.h
|
||||
Settings/PathPane.cpp
|
||||
Settings/PathPane.h
|
||||
Settings/USBDeviceAddToWhitelistDialog.cpp
|
||||
Settings/USBDeviceAddToWhitelistDialog.h
|
||||
Settings/USBDevicePicker.cpp
|
||||
Settings/USBDevicePicker.h
|
||||
Settings/WiiPane.cpp
|
||||
Settings/WiiPane.h
|
||||
SkylanderPortal/SkylanderModifyDialog.cpp
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "DolphinQt/QtUtils/QueueOnObject.h"
|
||||
#include "DolphinQt/QtUtils/SignalBlocking.h"
|
||||
#include "DolphinQt/Settings.h"
|
||||
#include "DolphinQt/Settings/USBDevicePicker.h"
|
||||
|
||||
WiimoteControllersWidget::WiimoteControllersWidget(QWidget* parent) : QWidget(parent)
|
||||
{
|
||||
|
@ -133,6 +134,9 @@ void WiimoteControllersWidget::OnBluetoothAdapterRefreshComplete(
|
|||
m_bluetooth_adapters->addItem(device_info, QVariant::fromValue(disconnected_device));
|
||||
m_bluetooth_adapters->setCurrentIndex(m_bluetooth_adapters->count() - 1);
|
||||
}
|
||||
|
||||
m_bluetooth_adapters->insertSeparator(m_bluetooth_adapters->count());
|
||||
m_bluetooth_adapters->addItem(tr("More Options..."));
|
||||
}
|
||||
|
||||
static int GetRadioButtonIndicatorWidth()
|
||||
|
@ -299,6 +303,8 @@ void WiimoteControllersWidget::ConnectWidgets()
|
|||
|
||||
void WiimoteControllersWidget::OnBluetoothPassthroughDeviceChanged(int index)
|
||||
{
|
||||
std::optional<USBUtils::DeviceInfo> device_info;
|
||||
bool needs_refresh = false;
|
||||
// "Automatic" selection
|
||||
if (index == 0)
|
||||
{
|
||||
|
@ -308,19 +314,31 @@ void WiimoteControllersWidget::OnBluetoothPassthroughDeviceChanged(int index)
|
|||
Config::MAIN_BLUETOOTH_PASSTHROUGH_VID);
|
||||
return;
|
||||
}
|
||||
|
||||
const QVariant item_data = m_bluetooth_adapters->itemData(index);
|
||||
|
||||
if (!item_data.isValid() || !item_data.canConvert<USBUtils::DeviceInfo>())
|
||||
// "More Options..." selection
|
||||
else if (index == m_bluetooth_adapters->count() - 1)
|
||||
{
|
||||
ERROR_LOG_FMT(COMMON, "Invalid Bluetooth device info selected in WiimoteControllersWidget");
|
||||
return;
|
||||
device_info = USBDevicePicker::Run(this, tr("Select A Bluetooth Device"));
|
||||
needs_refresh = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
const QVariant item_data = m_bluetooth_adapters->itemData(index);
|
||||
|
||||
if (!item_data.isValid() || !item_data.canConvert<USBUtils::DeviceInfo>())
|
||||
{
|
||||
ERROR_LOG_FMT(COMMON, "Invalid Bluetooth device info selected in WiimoteControllersWidget");
|
||||
return;
|
||||
}
|
||||
device_info = item_data.value<USBUtils::DeviceInfo>();
|
||||
}
|
||||
|
||||
const auto& device_info = item_data.value<USBUtils::DeviceInfo>();
|
||||
|
||||
Config::SetBaseOrCurrent(Config::MAIN_BLUETOOTH_PASSTHROUGH_PID, device_info.pid);
|
||||
Config::SetBaseOrCurrent(Config::MAIN_BLUETOOTH_PASSTHROUGH_VID, device_info.vid);
|
||||
if (device_info.has_value())
|
||||
{
|
||||
Config::SetBaseOrCurrent(Config::MAIN_BLUETOOTH_PASSTHROUGH_PID, device_info->pid);
|
||||
Config::SetBaseOrCurrent(Config::MAIN_BLUETOOTH_PASSTHROUGH_VID, device_info->vid);
|
||||
}
|
||||
if (needs_refresh)
|
||||
StartBluetoothAdapterRefresh();
|
||||
}
|
||||
|
||||
void WiimoteControllersWidget::OnBluetoothPassthroughResetPressed()
|
||||
|
|
|
@ -219,7 +219,7 @@
|
|||
<ClCompile Include="Settings\GeneralPane.cpp" />
|
||||
<ClCompile Include="Settings\InterfacePane.cpp" />
|
||||
<ClCompile Include="Settings\PathPane.cpp" />
|
||||
<ClCompile Include="Settings\USBDeviceAddToWhitelistDialog.cpp" />
|
||||
<ClCompile Include="Settings\USBDevicePicker.cpp" />
|
||||
<ClCompile Include="Settings\WiiPane.cpp" />
|
||||
<ClCompile Include="SkylanderPortal\SkylanderModifyDialog.cpp" />
|
||||
<ClCompile Include="SkylanderPortal\SkylanderPortalWindow.cpp" />
|
||||
|
@ -429,7 +429,7 @@
|
|||
<QtMoc Include="Settings\GeneralPane.h" />
|
||||
<QtMoc Include="Settings\InterfacePane.h" />
|
||||
<QtMoc Include="Settings\PathPane.h" />
|
||||
<QtMoc Include="Settings\USBDeviceAddToWhitelistDialog.h" />
|
||||
<QtMoc Include="Settings\USBDevicePicker.h" />
|
||||
<QtMoc Include="Settings\WiiPane.h" />
|
||||
<QtMoc Include="SkylanderPortal\SkylanderPortalWindow.h" />
|
||||
<QtMoc Include="TAS\GCTASInputWindow.h" />
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
// Copyright 2017 Dolphin Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "DolphinQt/Settings/USBDeviceAddToWhitelistDialog.h"
|
||||
#include "DolphinQt/Settings/USBDevicePicker.h"
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include <QDialog>
|
||||
#include <QDialogButtonBox>
|
||||
|
@ -18,23 +20,12 @@
|
|||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "Common/StringUtil.h"
|
||||
|
||||
#include "Core/Config/MainSettings.h"
|
||||
#include "Core/ConfigManager.h"
|
||||
#include "Core/USBUtils.h"
|
||||
|
||||
#include "DolphinQt/QtUtils/ModalMessageBox.h"
|
||||
#include "DolphinQt/Settings/WiiPane.h"
|
||||
|
||||
static bool IsValidUSBIDString(const std::string& string)
|
||||
{
|
||||
if (string.empty() || string.length() > 4)
|
||||
return false;
|
||||
return std::ranges::all_of(string, Common::IsXDigit);
|
||||
}
|
||||
|
||||
USBDeviceAddToWhitelistDialog::USBDeviceAddToWhitelistDialog(QWidget* parent) : QDialog(parent)
|
||||
USBDevicePicker::USBDevicePicker(QWidget* parent, FilterFunctionType filter)
|
||||
: QDialog(parent), m_filter(std::move(filter))
|
||||
{
|
||||
InitControls();
|
||||
setLayout(main_layout);
|
||||
|
@ -42,19 +33,28 @@ USBDeviceAddToWhitelistDialog::USBDeviceAddToWhitelistDialog(QWidget* parent) :
|
|||
adjustSize();
|
||||
}
|
||||
|
||||
void USBDeviceAddToWhitelistDialog::InitControls()
|
||||
std::optional<USBUtils::DeviceInfo> USBDevicePicker::Run(QWidget* parent, const QString& title,
|
||||
FilterFunctionType filter)
|
||||
{
|
||||
setWindowTitle(tr("Add New USB Device"));
|
||||
USBDevicePicker picker(parent, std::move(filter));
|
||||
picker.setWindowTitle(title);
|
||||
|
||||
m_whitelist_buttonbox = new QDialogButtonBox();
|
||||
auto* add_button = new QPushButton(tr("Add"));
|
||||
if (picker.exec() == QDialog::Accepted)
|
||||
return picker.GetSelectedDevice();
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
void USBDevicePicker::InitControls()
|
||||
{
|
||||
m_picker_buttonbox = new QDialogButtonBox();
|
||||
auto* select_button = new QPushButton(tr("Select"));
|
||||
auto* cancel_button = new QPushButton(tr("Cancel"));
|
||||
m_whitelist_buttonbox->addButton(add_button, QDialogButtonBox::AcceptRole);
|
||||
m_whitelist_buttonbox->addButton(cancel_button, QDialogButtonBox::RejectRole);
|
||||
connect(add_button, &QPushButton::clicked, this,
|
||||
&USBDeviceAddToWhitelistDialog::AddUSBDeviceToWhitelist);
|
||||
connect(cancel_button, &QPushButton::clicked, this, &USBDeviceAddToWhitelistDialog::reject);
|
||||
add_button->setDefault(true);
|
||||
m_picker_buttonbox->addButton(select_button, QDialogButtonBox::AcceptRole);
|
||||
m_picker_buttonbox->addButton(cancel_button, QDialogButtonBox::RejectRole);
|
||||
connect(select_button, &QPushButton::clicked, this, &QDialog::accept);
|
||||
connect(cancel_button, &QPushButton::clicked, this, &QDialog::reject);
|
||||
select_button->setDefault(true);
|
||||
|
||||
main_layout = new QVBoxLayout();
|
||||
enter_device_id_label = new QLabel(tr("Enter USB device ID"));
|
||||
|
@ -87,31 +87,33 @@ void USBDeviceAddToWhitelistDialog::InitControls()
|
|||
usb_inserted_devices_list = new QListWidget();
|
||||
m_refresh_devices_timer = new QTimer(this);
|
||||
connect(usb_inserted_devices_list, &QListWidget::currentItemChanged, this,
|
||||
&USBDeviceAddToWhitelistDialog::OnDeviceSelection);
|
||||
connect(usb_inserted_devices_list, &QListWidget::itemDoubleClicked, add_button,
|
||||
&USBDevicePicker::OnDeviceSelection);
|
||||
connect(usb_inserted_devices_list, &QListWidget::itemDoubleClicked, select_button,
|
||||
&QPushButton::clicked);
|
||||
connect(m_refresh_devices_timer, &QTimer::timeout, this,
|
||||
&USBDeviceAddToWhitelistDialog::RefreshDeviceList);
|
||||
connect(m_refresh_devices_timer, &QTimer::timeout, this, &USBDevicePicker::RefreshDeviceList);
|
||||
RefreshDeviceList();
|
||||
m_refresh_devices_timer->start(1000);
|
||||
|
||||
main_layout->addWidget(usb_inserted_devices_list);
|
||||
main_layout->addWidget(m_whitelist_buttonbox);
|
||||
main_layout->addWidget(m_picker_buttonbox);
|
||||
|
||||
// i18n: VID means Vendor ID (in the context of a USB device)
|
||||
device_vid_textbox->setPlaceholderText(tr("Device VID"));
|
||||
// i18n: PID means Product ID (in the context of a USB device), not Process ID
|
||||
device_pid_textbox->setPlaceholderText(tr("Device PID"));
|
||||
|
||||
const QRegularExpression hex_regex(QStringLiteral("^[0-9A-Fa-f]*$"));
|
||||
const QRegularExpressionValidator* hex_validator =
|
||||
new QRegularExpressionValidator(hex_regex, this);
|
||||
device_vid_textbox->setValidator(hex_validator);
|
||||
device_vid_textbox->setMaxLength(4);
|
||||
device_pid_textbox->setValidator(hex_validator);
|
||||
device_pid_textbox->setMaxLength(4);
|
||||
}
|
||||
void USBDeviceAddToWhitelistDialog::RefreshDeviceList()
|
||||
{
|
||||
const auto whitelist = Config::GetUSBDeviceWhitelist();
|
||||
|
||||
const auto& current_devices = USBUtils::ListDevices(
|
||||
[&whitelist](const USBUtils::DeviceInfo& device) { return !whitelist.contains(device); });
|
||||
void USBDevicePicker::RefreshDeviceList()
|
||||
{
|
||||
const auto& current_devices = USBUtils::ListDevices(m_filter);
|
||||
|
||||
if (current_devices == m_shown_devices)
|
||||
return;
|
||||
|
@ -129,44 +131,7 @@ void USBDeviceAddToWhitelistDialog::RefreshDeviceList()
|
|||
|
||||
m_shown_devices = current_devices;
|
||||
}
|
||||
|
||||
void USBDeviceAddToWhitelistDialog::AddUSBDeviceToWhitelist()
|
||||
{
|
||||
const std::string vid_string(StripWhitespace(device_vid_textbox->text().toStdString()));
|
||||
const std::string pid_string(StripWhitespace(device_pid_textbox->text().toStdString()));
|
||||
if (!IsValidUSBIDString(vid_string))
|
||||
{
|
||||
ModalMessageBox::critical(this, tr("USB Whitelist Error"),
|
||||
// i18n: Here, VID means Vendor ID (for a USB device).
|
||||
tr("The entered VID is invalid."));
|
||||
return;
|
||||
}
|
||||
if (!IsValidUSBIDString(pid_string))
|
||||
{
|
||||
ModalMessageBox::critical(this, tr("USB Whitelist Error"),
|
||||
// i18n: Here, PID means Product ID (for a USB device).
|
||||
tr("The entered PID is invalid."));
|
||||
return;
|
||||
}
|
||||
|
||||
const u16 vid = static_cast<u16>(std::stoul(vid_string, nullptr, 16));
|
||||
const u16 pid = static_cast<u16>(std::stoul(pid_string, nullptr, 16));
|
||||
const USBUtils::DeviceInfo new_device{vid, pid};
|
||||
|
||||
auto whitelist = Config::GetUSBDeviceWhitelist();
|
||||
if (whitelist.contains(new_device))
|
||||
{
|
||||
ModalMessageBox::critical(this, tr("USB Whitelist Error"),
|
||||
tr("This USB device is already whitelisted."));
|
||||
return;
|
||||
}
|
||||
whitelist.emplace(new_device);
|
||||
Config::SetUSBDeviceWhitelist(whitelist);
|
||||
Config::Save();
|
||||
accept();
|
||||
}
|
||||
|
||||
void USBDeviceAddToWhitelistDialog::OnDeviceSelection()
|
||||
void USBDevicePicker::OnDeviceSelection()
|
||||
{
|
||||
auto* current_item = usb_inserted_devices_list->currentItem();
|
||||
if (!current_item)
|
||||
|
@ -178,3 +143,19 @@ void USBDeviceAddToWhitelistDialog::OnDeviceSelection()
|
|||
device_vid_textbox->setText(QString::fromStdString(fmt::format("{:04x}", device.vid)));
|
||||
device_pid_textbox->setText(QString::fromStdString(fmt::format("{:04x}", device.pid)));
|
||||
}
|
||||
|
||||
std::optional<USBUtils::DeviceInfo> USBDevicePicker::GetSelectedDevice() const
|
||||
{
|
||||
const std::string vid_string(device_vid_textbox->text().toStdString());
|
||||
const std::string pid_string(device_pid_textbox->text().toStdString());
|
||||
|
||||
if (vid_string.empty() || pid_string.empty())
|
||||
return std::nullopt;
|
||||
|
||||
const u16 vid = static_cast<u16>(std::stoul(vid_string, nullptr, 16));
|
||||
const u16 pid = static_cast<u16>(std::stoul(pid_string, nullptr, 16));
|
||||
|
||||
const USBUtils::DeviceInfo device{vid, pid};
|
||||
|
||||
return device;
|
||||
}
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
#include <QDialog>
|
||||
|
@ -24,16 +25,21 @@ class QPushButton;
|
|||
class QErrorMessage;
|
||||
class QMessageBox;
|
||||
|
||||
class USBDeviceAddToWhitelistDialog final : public QDialog
|
||||
class USBDevicePicker final : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit USBDeviceAddToWhitelistDialog(QWidget* parent);
|
||||
using FilterFunctionType = std::function<bool(const USBUtils::DeviceInfo&)>;
|
||||
explicit USBDevicePicker(QWidget* parent, FilterFunctionType filter);
|
||||
|
||||
static std::optional<USBUtils::DeviceInfo> Run(
|
||||
QWidget* parent, const QString& title,
|
||||
const FilterFunctionType filter = [](const USBUtils::DeviceInfo&) { return true; });
|
||||
|
||||
private:
|
||||
static constexpr int DEVICE_REFRESH_INTERVAL_MS = 100;
|
||||
QTimer* m_refresh_devices_timer;
|
||||
QDialogButtonBox* m_whitelist_buttonbox;
|
||||
QDialogButtonBox* m_picker_buttonbox;
|
||||
QVBoxLayout* main_layout;
|
||||
QLabel* enter_device_id_label;
|
||||
QHBoxLayout* entry_hbox_layout;
|
||||
|
@ -42,9 +48,12 @@ private:
|
|||
QLabel* select_label;
|
||||
QListWidget* usb_inserted_devices_list;
|
||||
|
||||
FilterFunctionType m_filter;
|
||||
|
||||
std::optional<USBUtils::DeviceInfo> GetSelectedDevice() const;
|
||||
|
||||
void InitControls();
|
||||
void RefreshDeviceList();
|
||||
void AddUSBDeviceToWhitelist();
|
||||
|
||||
void OnDeviceSelection();
|
||||
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include <array>
|
||||
#include <future>
|
||||
#include <optional>
|
||||
#include <utility>
|
||||
|
||||
#include <QCheckBox>
|
||||
|
@ -39,7 +40,7 @@
|
|||
#include "DolphinQt/QtUtils/QtUtils.h"
|
||||
#include "DolphinQt/QtUtils/SignalBlocking.h"
|
||||
#include "DolphinQt/Settings.h"
|
||||
#include "DolphinQt/Settings/USBDeviceAddToWhitelistDialog.h"
|
||||
#include "DolphinQt/Settings/USBDevicePicker.h"
|
||||
|
||||
// SYSCONF uses 0 for bottom and 1 for top, but we place them in
|
||||
// the other order in the GUI so that Top will be above Bottom,
|
||||
|
@ -460,10 +461,24 @@ void WiiPane::ValidateSelectionState()
|
|||
|
||||
void WiiPane::OnUSBWhitelistAddButton()
|
||||
{
|
||||
USBDeviceAddToWhitelistDialog usb_whitelist_dialog(this);
|
||||
connect(&usb_whitelist_dialog, &USBDeviceAddToWhitelistDialog::accepted, this,
|
||||
&WiiPane::PopulateUSBPassthroughListWidget);
|
||||
usb_whitelist_dialog.exec();
|
||||
auto whitelist = Config::GetUSBDeviceWhitelist();
|
||||
|
||||
const std::optional<USBUtils::DeviceInfo> usb_device = USBDevicePicker::Run(
|
||||
this, tr("Add New USB Device"),
|
||||
[&whitelist](const USBUtils::DeviceInfo& device) { return !whitelist.contains(device); });
|
||||
if (!usb_device)
|
||||
return;
|
||||
|
||||
if (whitelist.contains(*usb_device))
|
||||
{
|
||||
ModalMessageBox::critical(this, tr("USB Whitelist Error"),
|
||||
tr("This USB device is already whitelisted."));
|
||||
return;
|
||||
}
|
||||
whitelist.emplace(*usb_device);
|
||||
Config::SetUSBDeviceWhitelist(whitelist);
|
||||
Config::Save();
|
||||
PopulateUSBPassthroughListWidget();
|
||||
}
|
||||
|
||||
void WiiPane::OnUSBWhitelistRemoveButton()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue