From 072c289f5e277a4319193a386111aac21339159c Mon Sep 17 00:00:00 2001 From: Megamouse Date: Sun, 8 May 2022 20:18:42 +0200 Subject: [PATCH] Qt: add new vfs usb tab --- Utilities/Config.cpp | 2 +- Utilities/Config.h | 6 +- rpcs3/rpcs3.vcxproj | 53 ++++++- rpcs3/rpcs3.vcxproj.filters | 36 +++++ rpcs3/rpcs3qt/CMakeLists.txt | 3 + rpcs3/rpcs3qt/gui_settings.h | 1 + rpcs3/rpcs3qt/log_frame.cpp | 4 +- rpcs3/rpcs3qt/log_frame.h | 2 +- rpcs3/rpcs3qt/main_window.cpp | 2 +- rpcs3/rpcs3qt/vfs_dialog.cpp | 55 ++++---- rpcs3/rpcs3qt/vfs_dialog.h | 4 +- rpcs3/rpcs3qt/vfs_dialog_path_widget.cpp | 108 +++++++++++++++ rpcs3/rpcs3qt/vfs_dialog_path_widget.h | 41 ++++++ rpcs3/rpcs3qt/vfs_dialog_tab.cpp | 108 +-------------- rpcs3/rpcs3qt/vfs_dialog_tab.h | 35 +---- rpcs3/rpcs3qt/vfs_dialog_usb_input.cpp | 97 +++++++++++++ rpcs3/rpcs3qt/vfs_dialog_usb_input.h | 29 ++++ rpcs3/rpcs3qt/vfs_dialog_usb_tab.cpp | 167 +++++++++++++++++++++++ rpcs3/rpcs3qt/vfs_dialog_usb_tab.h | 37 +++++ 19 files changed, 623 insertions(+), 167 deletions(-) create mode 100644 rpcs3/rpcs3qt/vfs_dialog_path_widget.cpp create mode 100644 rpcs3/rpcs3qt/vfs_dialog_path_widget.h create mode 100644 rpcs3/rpcs3qt/vfs_dialog_usb_input.cpp create mode 100644 rpcs3/rpcs3qt/vfs_dialog_usb_input.h create mode 100644 rpcs3/rpcs3qt/vfs_dialog_usb_tab.cpp create mode 100644 rpcs3/rpcs3qt/vfs_dialog_usb_tab.h diff --git a/Utilities/Config.cpp b/Utilities/Config.cpp index f03d06b1d8..9f2387dae1 100644 --- a/Utilities/Config.cpp +++ b/Utilities/Config.cpp @@ -518,5 +518,5 @@ void cfg::device_entry::set_map(map_of_type&& map) void cfg::device_entry::from_default() { - m_map = m_def; + m_map = m_default; } diff --git a/Utilities/Config.h b/Utilities/Config.h index b28802964b..c8cc8b1a75 100644 --- a/Utilities/Config.h +++ b/Utilities/Config.h @@ -534,14 +534,14 @@ namespace cfg class device_entry final : public _base { map_of_type m_map{}; - map_of_type m_def{}; + map_of_type m_default{}; public: device_entry(node* owner, const std::string& name, map_of_type def = {}) : _base(type::device, owner, name, true) , m_map(std::move(def)) { - m_def = m_map; + m_default = m_map; } const map_of_type& get_map() const @@ -551,7 +551,7 @@ namespace cfg const map_of_type& get_default() const { - return m_def; + return m_default; } void set_map(map_of_type&& map); diff --git a/rpcs3/rpcs3.vcxproj b/rpcs3/rpcs3.vcxproj index 851a85a9a1..fa75ee7604 100644 --- a/rpcs3/rpcs3.vcxproj +++ b/rpcs3/rpcs3.vcxproj @@ -375,9 +375,18 @@ true + + true + true + + true + + + true + true @@ -582,9 +591,18 @@ true + + true + true + + true + + + true + true @@ -629,6 +647,9 @@ + + + @@ -1190,6 +1211,36 @@ "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DWITH_DISCORD_RPC -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DNDEBUG -DQT_WINEXTRAS_LIB -DQT_CONCURRENT_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\wolfssl\wolfssl" "-I.\..\3rdparty\curl\curl\include" "-I.\..\3rdparty\libusb\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I.\..\3rdparty\XAudio2Redist\include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtCore" "-I.\release" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras" "-I$(QTDIR)\include\QtConcurrent" + + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing %(Identity)... + .\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DWIN32_LEAN_AND_MEAN -DHAVE_VULKAN -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_WINEXTRAS_LIB -DQT_CONCURRENT_LIB -DQT_MULTIMEDIA_LIB -DQT_MULTIMEDIAWIDGETS_LIB -DQT_SVG_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\SoundTouch\soundtouch\include" "-I.\..\3rdparty\cubeb\extra" "-I.\..\3rdparty\cubeb\cubeb\include" "-I.\..\3rdparty\flatbuffers\include" "-I.\..\3rdparty\wolfssl\wolfssl" "-I.\..\3rdparty\curl\curl\include" "-I.\..\3rdparty\libusb\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I.\..\3rdparty\XAudio2Redist\include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtCore" "-I.\debug" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtMultimedia" "-I$(QTDIR)\include\QtMultimediaWidgets" "-I$(QTDIR)\include\QtSvg" + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing %(Identity)... + .\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DWIN32_LEAN_AND_MEAN -DHAVE_VULKAN -DWITH_DISCORD_RPC -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DNDEBUG -DQT_WINEXTRAS_LIB -DQT_CONCURRENT_LIB -DQT_MULTIMEDIA_LIB -DQT_MULTIMEDIAWIDGETS_LIB -DQT_SVG_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\SoundTouch\soundtouch\include" "-I.\..\3rdparty\cubeb\extra" "-I.\..\3rdparty\cubeb\cubeb\include" "-I.\..\3rdparty\flatbuffers\include" "-I.\..\3rdparty\wolfssl\wolfssl" "-I.\..\3rdparty\curl\curl\include" "-I.\..\3rdparty\libusb\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I.\..\3rdparty\XAudio2Redist\include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtCore" "-I.\release" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtMultimedia" "-I$(QTDIR)\include\QtMultimediaWidgets" "-I$(QTDIR)\include\QtSvg" + + + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing %(Identity)... + .\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DWIN32_LEAN_AND_MEAN -DHAVE_VULKAN -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_WINEXTRAS_LIB -DQT_CONCURRENT_LIB -DQT_MULTIMEDIA_LIB -DQT_MULTIMEDIAWIDGETS_LIB -DQT_SVG_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\SoundTouch\soundtouch\include" "-I.\..\3rdparty\cubeb\extra" "-I.\..\3rdparty\cubeb\cubeb\include" "-I.\..\3rdparty\flatbuffers\include" "-I.\..\3rdparty\wolfssl\wolfssl" "-I.\..\3rdparty\curl\curl\include" "-I.\..\3rdparty\libusb\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I.\..\3rdparty\XAudio2Redist\include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtCore" "-I.\debug" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtMultimedia" "-I$(QTDIR)\include\QtMultimediaWidgets" "-I$(QTDIR)\include\QtSvg" + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing %(Identity)... + .\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DWIN32_LEAN_AND_MEAN -DHAVE_VULKAN -DWITH_DISCORD_RPC -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DNDEBUG -DQT_WINEXTRAS_LIB -DQT_CONCURRENT_LIB -DQT_MULTIMEDIA_LIB -DQT_MULTIMEDIAWIDGETS_LIB -DQT_SVG_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\SoundTouch\soundtouch\include" "-I.\..\3rdparty\cubeb\extra" "-I.\..\3rdparty\cubeb\cubeb\include" "-I.\..\3rdparty\flatbuffers\include" "-I.\..\3rdparty\wolfssl\wolfssl" "-I.\..\3rdparty\curl\curl\include" "-I.\..\3rdparty\libusb\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I.\..\3rdparty\XAudio2Redist\include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtCore" "-I.\release" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtMultimedia" "-I$(QTDIR)\include\QtMultimediaWidgets" "-I$(QTDIR)\include\QtSvg" + + + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing %(Identity)... + .\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DWIN32_LEAN_AND_MEAN -DHAVE_VULKAN -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_WINEXTRAS_LIB -DQT_CONCURRENT_LIB -DQT_MULTIMEDIA_LIB -DQT_MULTIMEDIAWIDGETS_LIB -DQT_SVG_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\SoundTouch\soundtouch\include" "-I.\..\3rdparty\cubeb\extra" "-I.\..\3rdparty\cubeb\cubeb\include" "-I.\..\3rdparty\flatbuffers\include" "-I.\..\3rdparty\wolfssl\wolfssl" "-I.\..\3rdparty\curl\curl\include" "-I.\..\3rdparty\libusb\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I.\..\3rdparty\XAudio2Redist\include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtCore" "-I.\debug" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtMultimedia" "-I$(QTDIR)\include\QtMultimediaWidgets" "-I$(QTDIR)\include\QtSvg" + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing %(Identity)... + .\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DWIN32_LEAN_AND_MEAN -DHAVE_VULKAN -DWITH_DISCORD_RPC -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DNDEBUG -DQT_WINEXTRAS_LIB -DQT_CONCURRENT_LIB -DQT_MULTIMEDIA_LIB -DQT_MULTIMEDIAWIDGETS_LIB -DQT_SVG_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\SoundTouch\soundtouch\include" "-I.\..\3rdparty\cubeb\extra" "-I.\..\3rdparty\cubeb\cubeb\include" "-I.\..\3rdparty\flatbuffers\include" "-I.\..\3rdparty\wolfssl\wolfssl" "-I.\..\3rdparty\curl\curl\include" "-I.\..\3rdparty\libusb\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I.\..\3rdparty\XAudio2Redist\include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtCore" "-I.\release" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtMultimedia" "-I$(QTDIR)\include\QtMultimediaWidgets" "-I$(QTDIR)\include\QtSvg" + $(QTDIR)\bin\moc.exe;%(FullPath) @@ -1538,4 +1589,4 @@ - + \ No newline at end of file diff --git a/rpcs3/rpcs3.vcxproj.filters b/rpcs3/rpcs3.vcxproj.filters index dc31ace380..a6f3e03dde 100644 --- a/rpcs3/rpcs3.vcxproj.filters +++ b/rpcs3/rpcs3.vcxproj.filters @@ -822,6 +822,33 @@ Generated Files\Release + + Gui\vfs + + + Generated Files\Debug + + + Generated Files\Release + + + Gui\vfs + + + Generated Files\Debug + + + Generated Files\Release + + + Gui\vfs + + + Generated Files\Debug + + + Generated Files\Release + @@ -1210,6 +1237,15 @@ Io\music + + Gui\vfs + + + Gui\vfs + + + Gui\vfs + diff --git a/rpcs3/rpcs3qt/CMakeLists.txt b/rpcs3/rpcs3qt/CMakeLists.txt index 82fa2ebd27..53b805a226 100644 --- a/rpcs3/rpcs3qt/CMakeLists.txt +++ b/rpcs3/rpcs3qt/CMakeLists.txt @@ -81,7 +81,10 @@ set(SRC_FILES user_account.cpp user_manager_dialog.cpp vfs_dialog.cpp + vfs_dialog_path_widget.cpp vfs_dialog_tab.cpp + vfs_dialog_usb_input.cpp + vfs_dialog_usb_tab.cpp welcome_dialog.cpp ) diff --git a/rpcs3/rpcs3qt/gui_settings.h b/rpcs3/rpcs3qt/gui_settings.h index f657d2f54b..00c980a2a4 100644 --- a/rpcs3/rpcs3qt/gui_settings.h +++ b/rpcs3/rpcs3qt/gui_settings.h @@ -182,6 +182,7 @@ namespace gui const gui_save fs_dev_flash_list = gui_save(fs, "dev_flash_list", QStringList()); const gui_save fs_dev_flash2_list = gui_save(fs, "dev_flash2_list", QStringList()); const gui_save fs_dev_flash3_list = gui_save(fs, "dev_flash3_list", QStringList()); + const gui_save fs_dev_usb_list = gui_save(fs, "dev_usb00X_list", QStringList()); // Used as a template for all usb paths const gui_save l_tty = gui_save(logger, "TTY", true); const gui_save l_level = gui_save(logger, "level", static_cast(logs::level::success)); diff --git a/rpcs3/rpcs3qt/log_frame.cpp b/rpcs3/rpcs3qt/log_frame.cpp index 6c68eeb518..a11adad726 100644 --- a/rpcs3/rpcs3qt/log_frame.cpp +++ b/rpcs3/rpcs3qt/log_frame.cpp @@ -105,8 +105,8 @@ struct gui_listener : logs::listener // GUI Listener instance static gui_listener s_gui_listener; -log_frame::log_frame(std::shared_ptr guiSettings, QWidget *parent) - : custom_dock_widget(tr("Log"), parent), m_gui_settings(std::move(guiSettings)) +log_frame::log_frame(std::shared_ptr _gui_settings, QWidget* parent) + : custom_dock_widget(tr("Log"), parent), m_gui_settings(std::move(_gui_settings)) { const int max_block_count_log = m_gui_settings->GetValue(gui::l_limit).toInt(); const int max_block_count_tty = m_gui_settings->GetValue(gui::l_limit_tty).toInt(); diff --git a/rpcs3/rpcs3qt/log_frame.h b/rpcs3/rpcs3qt/log_frame.h index 66b2c048e2..d4f9900f1a 100644 --- a/rpcs3/rpcs3qt/log_frame.h +++ b/rpcs3/rpcs3qt/log_frame.h @@ -19,7 +19,7 @@ class log_frame : public custom_dock_widget Q_OBJECT public: - explicit log_frame(std::shared_ptr guiSettings, QWidget *parent = nullptr); + explicit log_frame(std::shared_ptr _gui_settings, QWidget* parent = nullptr); /** Repaint log colors after new stylesheet was applied */ void RepaintTextColors(); diff --git a/rpcs3/rpcs3qt/main_window.cpp b/rpcs3/rpcs3qt/main_window.cpp index c68dbd1c8a..9f0794cf18 100644 --- a/rpcs3/rpcs3qt/main_window.cpp +++ b/rpcs3/rpcs3qt/main_window.cpp @@ -2184,7 +2184,7 @@ void main_window::CreateConnects() connect(ui->confVFSDialogAct, &QAction::triggered, this, [this]() { - vfs_dialog dlg(m_gui_settings, m_emu_settings, this); + vfs_dialog dlg(m_gui_settings, this); dlg.exec(); ui->bootVSHAct->setEnabled(fs::is_file(g_cfg_vfs.get_dev_flash() + "vsh/module/vsh.self")); // dev_flash may have changed. Disable vsh if not present. m_game_list_frame->Refresh(true); // dev_hdd0 may have changed. Refresh just in case. diff --git a/rpcs3/rpcs3qt/vfs_dialog.cpp b/rpcs3/rpcs3qt/vfs_dialog.cpp index b3b5ed5abc..c5ca2c454c 100644 --- a/rpcs3/rpcs3qt/vfs_dialog.cpp +++ b/rpcs3/rpcs3qt/vfs_dialog.cpp @@ -1,5 +1,6 @@ #include "vfs_dialog.h" #include "vfs_dialog_tab.h" +#include "vfs_dialog_usb_tab.h" #include "gui_settings.h" #include @@ -13,32 +14,25 @@ inline std::string sstr(const QString& _in) { return _in.toStdString(); } -vfs_dialog::vfs_dialog(std::shared_ptr guiSettings, std::shared_ptr emuSettings, QWidget* parent) - : QDialog(parent), m_gui_settings(std::move(guiSettings)), m_emu_settings(std::move(emuSettings)) +vfs_dialog::vfs_dialog(std::shared_ptr _gui_settings, QWidget* parent) + : QDialog(parent), m_gui_settings(std::move(_gui_settings)) { + setWindowTitle(tr("Virtual File System")); + setObjectName("vfs_dialog"); + QTabWidget* tabs = new QTabWidget(); tabs->setUsesScrollButtons(false); g_cfg_vfs.load(); // Create tabs - vfs_dialog_tab* emulator_tab = new vfs_dialog_tab({ "$(EmulatorDir)", gui::fs_emulator_dir_list, &g_cfg_vfs.emulator_dir }, - m_gui_settings, this); - - vfs_dialog_tab* dev_hdd0_tab = new vfs_dialog_tab({ "dev_hdd0", gui::fs_dev_hdd0_list, &g_cfg_vfs.dev_hdd0 }, - m_gui_settings, this); - - vfs_dialog_tab* dev_hdd1_tab = new vfs_dialog_tab({ "dev_hdd1", gui::fs_dev_hdd1_list, &g_cfg_vfs.dev_hdd1 }, - m_gui_settings, this); - - vfs_dialog_tab* dev_flash_tab = new vfs_dialog_tab({ "dev_flash", gui::fs_dev_flash_list, &g_cfg_vfs.dev_flash }, - m_gui_settings, this); - - vfs_dialog_tab* dev_flash2_tab = new vfs_dialog_tab({ "dev_flash2", gui::fs_dev_flash2_list, &g_cfg_vfs.dev_flash2 }, - m_gui_settings, this); - - vfs_dialog_tab* dev_flash3_tab = new vfs_dialog_tab({ "dev_flash3", gui::fs_dev_flash3_list, &g_cfg_vfs.dev_flash3 }, - m_gui_settings, this); + vfs_dialog_tab* emulator_tab = new vfs_dialog_tab("$(EmulatorDir)", gui::fs_emulator_dir_list, &g_cfg_vfs.emulator_dir, m_gui_settings, this); + vfs_dialog_tab* dev_hdd0_tab = new vfs_dialog_tab("dev_hdd0", gui::fs_dev_hdd0_list, &g_cfg_vfs.dev_hdd0, m_gui_settings, this); + vfs_dialog_tab* dev_hdd1_tab = new vfs_dialog_tab("dev_hdd1", gui::fs_dev_hdd1_list, &g_cfg_vfs.dev_hdd1, m_gui_settings, this); + vfs_dialog_tab* dev_flash_tab = new vfs_dialog_tab("dev_flash", gui::fs_dev_flash_list, &g_cfg_vfs.dev_flash, m_gui_settings, this); + vfs_dialog_tab* dev_flash2_tab = new vfs_dialog_tab("dev_flash2", gui::fs_dev_flash2_list, &g_cfg_vfs.dev_flash2, m_gui_settings, this); + vfs_dialog_tab* dev_flash3_tab = new vfs_dialog_tab("dev_flash3", gui::fs_dev_flash3_list, &g_cfg_vfs.dev_flash3, m_gui_settings, this); + vfs_dialog_usb_tab* dev_usb_tab = new vfs_dialog_usb_tab(&g_cfg_vfs.dev_usb, m_gui_settings, this); tabs->addTab(emulator_tab, "$(EmulatorDir)"); tabs->addTab(dev_hdd0_tab, "dev_hdd0"); @@ -46,13 +40,14 @@ vfs_dialog::vfs_dialog(std::shared_ptr guiSettings, std::shared_pt tabs->addTab(dev_flash_tab, "dev_flash"); tabs->addTab(dev_flash2_tab, "dev_flash2"); tabs->addTab(dev_flash3_tab, "dev_flash3"); + tabs->addTab(dev_usb_tab, "dev_usb"); // Create buttons QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Close | QDialogButtonBox::Save | QDialogButtonBox::RestoreDefaults); buttons->button(QDialogButtonBox::RestoreDefaults)->setText(tr("Reset Directories")); buttons->button(QDialogButtonBox::Save)->setDefault(true); - connect(buttons, &QDialogButtonBox::clicked, [=, this](QAbstractButton* button) + connect(buttons, &QDialogButtonBox::clicked, this, [this, buttons, tabs](QAbstractButton* button) { if (button == buttons->button(QDialogButtonBox::RestoreDefaults)) { @@ -61,14 +56,28 @@ vfs_dialog::vfs_dialog(std::shared_ptr guiSettings, std::shared_pt for (int i = 0; i < tabs->count(); ++i) { - static_cast(tabs->widget(i))->Reset(); + if (i < tabs->count() - 1) + { + static_cast(tabs->widget(i))->reset(); + } + else + { + static_cast(tabs->widget(i))->reset(); + } } } else if (button == buttons->button(QDialogButtonBox::Save)) { for (int i = 0; i < tabs->count(); ++i) { - static_cast(tabs->widget(i))->SetSettings(); + if (i < tabs->count() - 1) + { + static_cast(tabs->widget(i))->set_settings(); + } + else + { + static_cast(tabs->widget(i))->set_settings(); + } } g_cfg_vfs.save(); @@ -92,8 +101,6 @@ vfs_dialog::vfs_dialog(std::shared_ptr guiSettings, std::shared_pt vbox->addWidget(buttons); setLayout(vbox); - setWindowTitle(tr("Virtual File System")); - setObjectName("vfs_dialog"); buttons->button(QDialogButtonBox::Save)->setFocus(); } diff --git a/rpcs3/rpcs3qt/vfs_dialog.h b/rpcs3/rpcs3qt/vfs_dialog.h index 89d59922bf..18adf2c115 100644 --- a/rpcs3/rpcs3qt/vfs_dialog.h +++ b/rpcs3/rpcs3qt/vfs_dialog.h @@ -3,15 +3,13 @@ #include class gui_settings; -class emu_settings; class vfs_dialog : public QDialog { Q_OBJECT public: - explicit vfs_dialog(std::shared_ptr guiSettings, std::shared_ptr emuSettings, QWidget* parent = nullptr); + explicit vfs_dialog(std::shared_ptr _gui_settings, QWidget* parent = nullptr); private: std::shared_ptr m_gui_settings; - std::shared_ptr m_emu_settings; }; diff --git a/rpcs3/rpcs3qt/vfs_dialog_path_widget.cpp b/rpcs3/rpcs3qt/vfs_dialog_path_widget.cpp new file mode 100644 index 0000000000..9e188eb632 --- /dev/null +++ b/rpcs3/rpcs3qt/vfs_dialog_path_widget.cpp @@ -0,0 +1,108 @@ +#include "vfs_dialog_path_widget.h" +#include "Utilities/Config.h" + +#include +#include +#include +#include + +vfs_dialog_path_widget::vfs_dialog_path_widget(const QString& name, const QString& current_path, QString default_path, gui_save list_location, std::shared_ptr _gui_settings, QWidget* parent) + : QWidget(parent), m_default_path(std::move(default_path)), m_list_location(std::move(list_location)), m_gui_settings(std::move(_gui_settings)) +{ + m_dir_list = new QListWidget(this); + + const QStringList all_dirs = m_gui_settings->GetValue(m_list_location).toStringList(); + + QListWidgetItem* selected_item = nullptr; + + for (const QString& dir : all_dirs) + { + QListWidgetItem* item = new QListWidgetItem(dir, m_dir_list); + if (dir == current_path) + selected_item = item; + } + + // We must show the currently selected config. + if (!selected_item) + selected_item = new QListWidgetItem(current_path, m_dir_list); + + selected_item->setSelected(true); + + m_dir_list->setMinimumWidth(m_dir_list->sizeHintForColumn(0)); + + QPushButton* add_directory_button = new QPushButton(QStringLiteral("+")); + add_directory_button->setToolTip(tr("Add new directory")); + add_directory_button->setFixedWidth(add_directory_button->sizeHint().height()); // Make button square + connect(add_directory_button, &QAbstractButton::clicked, this, &vfs_dialog_path_widget::add_new_directory); + + QPushButton* button_remove_dir = new QPushButton(QStringLiteral("-")); + button_remove_dir->setToolTip(tr("Remove directory")); + button_remove_dir->setFixedWidth(button_remove_dir->sizeHint().height()); // Make button square + button_remove_dir->setEnabled(false); + connect(button_remove_dir, &QAbstractButton::clicked, this, &vfs_dialog_path_widget::remove_directory); + + QHBoxLayout* selected_config_layout = new QHBoxLayout; + m_selected_config_label = new QLabel(current_path.isEmpty() ? EmptyPath : current_path); + selected_config_layout->addWidget(new QLabel(tr("%0 directory:").arg(name))); + selected_config_layout->addWidget(m_selected_config_label); + selected_config_layout->addStretch(); + selected_config_layout->addWidget(add_directory_button); + selected_config_layout->addWidget(button_remove_dir); + + QVBoxLayout* vbox = new QVBoxLayout; + vbox->addWidget(m_dir_list); + vbox->addLayout(selected_config_layout); + + setLayout(vbox); + + connect(m_dir_list, &QListWidget::currentRowChanged, this, [this, button_remove_dir](int row) + { + QListWidgetItem* item = m_dir_list->item(row); + m_selected_config_label->setText((item && !item->text().isEmpty()) ? item->text() : EmptyPath); + button_remove_dir->setEnabled(item && row > 0); + }); +} + +void vfs_dialog_path_widget::reset() const +{ + m_dir_list->clear(); + m_dir_list->setCurrentItem(new QListWidgetItem(m_default_path, m_dir_list)); +} + +void vfs_dialog_path_widget::add_new_directory() const +{ + QString dir = QFileDialog::getExistingDirectory(nullptr, tr("Choose a directory"), QCoreApplication::applicationDirPath(), QFileDialog::DontResolveSymlinks); + + if (dir.isEmpty()) + return; + + if (!dir.endsWith("/")) + dir += '/'; + + m_dir_list->setCurrentItem(new QListWidgetItem(dir, m_dir_list)); +} + +void vfs_dialog_path_widget::remove_directory() const +{ + const int row = m_dir_list->currentRow(); + if (row > 0) + { + QListWidgetItem* item = m_dir_list->item(row); + delete item; + } +} + +QStringList vfs_dialog_path_widget::get_dir_list() const +{ + QStringList all_dirs; + for (int i = 0; i < m_dir_list->count(); ++i) + { + all_dirs += m_dir_list->item(i)->text(); + } + return all_dirs; +} + +std::string vfs_dialog_path_widget::get_selected_path() const +{ + return m_selected_config_label->text() == EmptyPath ? "" : m_selected_config_label->text().toStdString(); +} diff --git a/rpcs3/rpcs3qt/vfs_dialog_path_widget.h b/rpcs3/rpcs3qt/vfs_dialog_path_widget.h new file mode 100644 index 0000000000..ea09a6e67c --- /dev/null +++ b/rpcs3/rpcs3qt/vfs_dialog_path_widget.h @@ -0,0 +1,41 @@ +#pragma once + +#include "util/types.hpp" +#include "gui_settings.h" + +#include +#include + +#include + +namespace cfg +{ + class string; +} + +class vfs_dialog_path_widget : public QWidget +{ + Q_OBJECT + +public: + explicit vfs_dialog_path_widget(const QString& name, const QString& current_path, QString default_path, gui_save list_location, std::shared_ptr _gui_settings, QWidget* parent = nullptr); + QStringList get_dir_list() const; + std::string get_selected_path() const; + + // Reset this widget without saving the settings yet + void reset() const; + +protected: + void add_new_directory() const; + void remove_directory() const; + + const QString EmptyPath = tr("Empty Path"); + + QString m_default_path; + gui_save m_list_location; + std::shared_ptr m_gui_settings; + + // UI variables needed in higher scope + QListWidget* m_dir_list; + QLabel* m_selected_config_label; +}; diff --git a/rpcs3/rpcs3qt/vfs_dialog_tab.cpp b/rpcs3/rpcs3qt/vfs_dialog_tab.cpp index d2c04f8d6a..93c640b84c 100644 --- a/rpcs3/rpcs3qt/vfs_dialog_tab.cpp +++ b/rpcs3/rpcs3qt/vfs_dialog_tab.cpp @@ -1,110 +1,14 @@ #include "vfs_dialog_tab.h" #include "Utilities/Config.h" -#include -#include -#include -#include - -constexpr auto qstr = QString::fromStdString; -inline std::string sstr(const QString& _in) { return _in.toStdString(); } - -vfs_dialog_tab::vfs_dialog_tab(vfs_settings_info settingsInfo, std::shared_ptr guiSettings, QWidget* parent) - : QWidget(parent), m_info(std::move(settingsInfo)), m_gui_settings(std::move(guiSettings)) +vfs_dialog_tab::vfs_dialog_tab(const QString& name, gui_save list_location, cfg::string* cfg_node, std::shared_ptr _gui_settings, QWidget* parent) + : vfs_dialog_path_widget(name, QString::fromStdString(cfg_node->to_string()), QString::fromStdString(cfg_node->def), std::move(list_location), std::move(_gui_settings), parent) + , m_cfg_node(cfg_node) { - m_dir_dist = new QListWidget(this); - - QStringList alldirs = m_gui_settings->GetValue(m_info.listLocation).toStringList(); - const QString current_dir = qstr(m_info.cfg_node->to_string()); - - QListWidgetItem* selected_item = nullptr; - - for (const QString& dir : alldirs) - { - QListWidgetItem* item = new QListWidgetItem(dir, m_dir_dist); - if (dir == current_dir) - selected_item = item; - } - - // We must show the currently selected config. - if (!selected_item) - selected_item = new QListWidgetItem(current_dir, m_dir_dist); - - selected_item->setSelected(true); - - m_dir_dist->setMinimumWidth(m_dir_dist->sizeHintForColumn(0)); - - QPushButton* addDir = new QPushButton(QStringLiteral("+")); - addDir->setToolTip(tr("Add new directory")); - addDir->setFixedWidth(addDir->sizeHint().height()); // Make button square - connect(addDir, &QAbstractButton::clicked, this, &vfs_dialog_tab::AddNewDirectory); - - QPushButton* button_remove_dir = new QPushButton(QStringLiteral("-")); - button_remove_dir->setToolTip(tr("Remove directory")); - button_remove_dir->setFixedWidth(button_remove_dir->sizeHint().height()); // Make button square - button_remove_dir->setEnabled(false); - connect(button_remove_dir, &QAbstractButton::clicked, this, &vfs_dialog_tab::RemoveDirectory); - - QHBoxLayout* selected_config_layout = new QHBoxLayout; - m_selected_config_label = new QLabel(current_dir.isEmpty() ? EmptyPath : current_dir); - selected_config_layout->addWidget(new QLabel(tr("%0 directory:").arg(m_info.name))); - selected_config_layout->addWidget(m_selected_config_label); - selected_config_layout->addStretch(); - selected_config_layout->addWidget(addDir); - selected_config_layout->addWidget(button_remove_dir); - - QVBoxLayout* vbox = new QVBoxLayout; - vbox->addWidget(m_dir_dist); - vbox->addLayout(selected_config_layout); - - setLayout(vbox); - - connect(m_dir_dist, &QListWidget::currentRowChanged, button_remove_dir, [this, button_remove_dir](int row) - { - QListWidgetItem* item = m_dir_dist->item(row); - m_selected_config_label->setText((item && !item->text().isEmpty()) ? item->text() : EmptyPath); - button_remove_dir->setEnabled(item && row > 0); - }); } -void vfs_dialog_tab::SetSettings() const +void vfs_dialog_tab::set_settings() const { - QStringList allDirs; - for (int i = 0; i < m_dir_dist->count(); ++i) - { - allDirs += m_dir_dist->item(i)->text(); - } - m_gui_settings->SetValue(m_info.listLocation, allDirs); - - const std::string new_dir = m_selected_config_label->text() == EmptyPath ? "" : sstr(m_selected_config_label->text()); - m_info.cfg_node->from_string(new_dir); -} - -void vfs_dialog_tab::Reset() const -{ - m_dir_dist->clear(); - m_dir_dist->setCurrentItem(new QListWidgetItem(qstr(m_info.cfg_node->def), m_dir_dist)); -} - -void vfs_dialog_tab::AddNewDirectory() const -{ - QString dir = QFileDialog::getExistingDirectory(nullptr, tr("Choose a directory"), QCoreApplication::applicationDirPath(), QFileDialog::DontResolveSymlinks); - - if (dir.isEmpty()) - return; - - if (!dir.endsWith("/")) - dir += '/'; - - m_dir_dist->setCurrentItem(new QListWidgetItem(dir, m_dir_dist)); -} - -void vfs_dialog_tab::RemoveDirectory() const -{ - const int row = m_dir_dist->currentRow(); - if (row > 0) - { - QListWidgetItem* item = m_dir_dist->item(row); - delete item; - } + m_gui_settings->SetValue(m_list_location, get_dir_list()); + m_cfg_node->from_string(get_selected_path()); } diff --git a/rpcs3/rpcs3qt/vfs_dialog_tab.h b/rpcs3/rpcs3qt/vfs_dialog_tab.h index 95d994c53a..213e115917 100644 --- a/rpcs3/rpcs3qt/vfs_dialog_tab.h +++ b/rpcs3/rpcs3qt/vfs_dialog_tab.h @@ -1,11 +1,6 @@ #pragma once -#include "util/types.hpp" - -#include "gui_settings.h" - -#include -#include +#include "vfs_dialog_path_widget.h" #include @@ -14,35 +9,17 @@ namespace cfg class string; } -struct vfs_settings_info -{ - QString name; // name of tab - gui_save listLocation; // Where the list of dir options are saved - cfg::string* cfg_node; // Needed since emu_settings overrides settings file and doesn't touch g_cfg currently. -}; +class gui_settings; -class vfs_dialog_tab : public QWidget +class vfs_dialog_tab : public vfs_dialog_path_widget { Q_OBJECT public: - explicit vfs_dialog_tab(vfs_settings_info info, std::shared_ptr guiSettings, QWidget* parent = nullptr); + explicit vfs_dialog_tab(const QString& name, gui_save list_location, cfg::string* cfg_node, std::shared_ptr _gui_settings, QWidget* parent = nullptr); - void SetSettings() const; - - // Reset this tab without saving the settings yet - void Reset() const; + void set_settings() const; private: - void AddNewDirectory() const; - void RemoveDirectory() const; - - const QString EmptyPath = tr("Empty Path"); - - vfs_settings_info m_info; - std::shared_ptr m_gui_settings; - - // UI variables needed in higher scope - QListWidget* m_dir_dist; - QLabel* m_selected_config_label; + cfg::string* m_cfg_node; }; diff --git a/rpcs3/rpcs3qt/vfs_dialog_usb_input.cpp b/rpcs3/rpcs3qt/vfs_dialog_usb_input.cpp new file mode 100644 index 0000000000..fbe803bdd1 --- /dev/null +++ b/rpcs3/rpcs3qt/vfs_dialog_usb_input.cpp @@ -0,0 +1,97 @@ +#include "vfs_dialog_usb_input.h" +#include "gui_settings.h" + +#include +#include +#include + +#include "Emu/vfs_config.h" + +inline std::string sstr(const QString& _in) { return _in.toStdString(); } + +vfs_dialog_usb_input::vfs_dialog_usb_input(const QString& name, const cfg::device_info& default_info, cfg::device_info* info, std::shared_ptr _gui_settings, QWidget* parent) + : QDialog(parent), m_gui_settings(std::move(_gui_settings)), m_gui_save(gui::fs_dev_usb_list) +{ + ensure(!!info); + ensure(name.back() >= '0' && name.back() <= '7'); + + setWindowTitle(tr("Edit %0").arg(name)); + setObjectName("vfs_dialog_usb_input"); + + m_gui_save.name.replace('X', name.back()); + + // Create path widget + m_path_widget = new vfs_dialog_path_widget(name, QString::fromStdString(info->path), QString::fromStdString(default_info.path), m_gui_save, m_gui_settings); + m_path_widget->layout()->setContentsMargins(0, 0, 0, 0); + + // Create buttons + QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Apply | QDialogButtonBox::RestoreDefaults); + buttons->button(QDialogButtonBox::RestoreDefaults)->setText(tr("Reset All")); + buttons->button(QDialogButtonBox::Apply)->setDefault(true); + + connect(buttons, &QDialogButtonBox::clicked, this, [this, buttons, info](QAbstractButton* button) + { + if (button == buttons->button(QDialogButtonBox::Apply)) + { + m_gui_settings->SetValue(m_gui_save, m_path_widget->get_dir_list()); + + info->path = m_path_widget->get_selected_path(); + info->vid = m_vid_edit->text().toStdString(); + info->pid = m_pid_edit->text().toStdString(); + info->serial = m_serial_edit->text().toStdString(); + + accept(); + } + else if (button == buttons->button(QDialogButtonBox::RestoreDefaults)) + { + if (QMessageBox::question(this, tr("Confirm Reset"), tr("Reset all entries and file system directories?")) != QMessageBox::Yes) + return; + + m_path_widget->reset(); + m_vid_edit->setText(""); + m_pid_edit->setText(""); + m_serial_edit->setText(""); + } + else if (button == buttons->button(QDialogButtonBox::Cancel)) + { + reject(); + } + }); + + m_vid_edit = new QLineEdit; + m_vid_edit->setMaxLength(4); + m_vid_edit->setValidator(new QRegularExpressionValidator(QRegularExpression("^[a-fA-F0-9]*$"))); // HEX only + m_vid_edit->setText(QString::fromStdString(info->vid)); + + m_pid_edit = new QLineEdit; + m_pid_edit->setMaxLength(4); + m_pid_edit->setValidator(new QRegularExpressionValidator(QRegularExpression("^[a-fA-F0-9]*$"))); // HEX only + m_pid_edit->setText(QString::fromStdString(info->pid)); + + m_serial_edit = new QLineEdit; + m_serial_edit->setMaxLength(64); // Max length defined in sys_fs + m_serial_edit->setText(QString::fromStdString(info->serial)); + + QVBoxLayout* vbox_left = new QVBoxLayout; + vbox_left->addWidget(new QLabel(tr("Vendor ID:"))); + vbox_left->addWidget(new QLabel(tr("Product ID:"))); + vbox_left->addWidget(new QLabel(tr("Serial:"))); + + QVBoxLayout* vbox_right = new QVBoxLayout; + vbox_right->addWidget(m_vid_edit); + vbox_right->addWidget(m_pid_edit); + vbox_right->addWidget(m_serial_edit); + + QHBoxLayout* hbox = new QHBoxLayout; + hbox->addLayout(vbox_left); + hbox->addLayout(vbox_right); + + QVBoxLayout* vbox = new QVBoxLayout; + vbox->addWidget(m_path_widget); + vbox->addLayout(hbox); + vbox->addWidget(buttons); + + setLayout(vbox); + + buttons->button(QDialogButtonBox::Apply)->setFocus(); +} diff --git a/rpcs3/rpcs3qt/vfs_dialog_usb_input.h b/rpcs3/rpcs3qt/vfs_dialog_usb_input.h new file mode 100644 index 0000000000..bcabae64aa --- /dev/null +++ b/rpcs3/rpcs3qt/vfs_dialog_usb_input.h @@ -0,0 +1,29 @@ +#pragma once + +#include "vfs_dialog_path_widget.h" + +#include +#include + +namespace cfg +{ + struct device_info; +} + +class gui_settings; + +class vfs_dialog_usb_input : public QDialog +{ + Q_OBJECT + +public: + explicit vfs_dialog_usb_input(const QString& name, const cfg::device_info& default_info, cfg::device_info* info, std::shared_ptr _gui_settings, QWidget* parent = nullptr); + +private: + std::shared_ptr m_gui_settings; + gui_save m_gui_save; + vfs_dialog_path_widget* m_path_widget; + QLineEdit* m_vid_edit = nullptr; + QLineEdit* m_pid_edit = nullptr; + QLineEdit* m_serial_edit = nullptr; +}; diff --git a/rpcs3/rpcs3qt/vfs_dialog_usb_tab.cpp b/rpcs3/rpcs3qt/vfs_dialog_usb_tab.cpp new file mode 100644 index 0000000000..c9befc9cba --- /dev/null +++ b/rpcs3/rpcs3qt/vfs_dialog_usb_tab.cpp @@ -0,0 +1,167 @@ +#include "vfs_dialog_usb_tab.h" +#include "vfs_dialog_usb_input.h" +#include "table_item_delegate.h" +#include "Utilities/Config.h" + +#include +#include +#include +#include + +constexpr int max_usb_devices = 8; + +const auto get_device_info = [](const QString& device_name, const cfg::map_of_type& device_map) -> cfg::device_info +{ + if (auto it = device_map.find(device_name.toStdString()); it != device_map.cend()) + { + return it->second; + } + + return {}; +}; + +const auto get_device_name = [](int i) -> QString +{ + return QString("/dev_usb00%0").arg(i); +}; + +enum usb_column : int +{ + usb_name = 0, + usb_path = 1, + usb_vid = 2, + usb_pid = 3, + usb_serial = 4 +}; + +vfs_dialog_usb_tab::vfs_dialog_usb_tab(cfg::device_entry* cfg_node, std::shared_ptr _gui_settings, QWidget* parent) + : QWidget(parent), m_cfg_node(cfg_node), m_gui_settings(std::move(_gui_settings)) +{ + m_usb_table = new QTableWidget(this); + m_usb_table->setItemDelegate(new table_item_delegate(this, false)); + m_usb_table->setShowGrid(false); + m_usb_table->setSelectionBehavior(QAbstractItemView::SelectRows); + m_usb_table->setEditTriggers(QAbstractItemView::NoEditTriggers); + m_usb_table->setContextMenuPolicy(Qt::CustomContextMenu); + m_usb_table->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); + m_usb_table->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel); + m_usb_table->verticalScrollBar()->setSingleStep(20); + m_usb_table->horizontalScrollBar()->setSingleStep(10); + m_usb_table->setColumnCount(5); + m_usb_table->setHorizontalHeaderLabels(QStringList() << tr("Device") << tr("Path") << tr("Vendor ID") << tr("Product ID") << tr("Serial")); + m_usb_table->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Fixed); + m_usb_table->horizontalHeader()->setStretchLastSection(true); + m_usb_table->setRowCount(max_usb_devices); + + for (int i = 0; i < max_usb_devices; i++) + { + const QString device_name = get_device_name(i); + const cfg::device_info info = get_device_info(device_name, m_cfg_node->get_map()); + + m_usb_table->setItem(i, usb_column::usb_name, new QTableWidgetItem(device_name)); + m_usb_table->setItem(i, usb_column::usb_path, new QTableWidgetItem(QString::fromStdString(info.path))); + m_usb_table->setItem(i, usb_column::usb_vid, new QTableWidgetItem(QString::fromStdString(info.vid))); + m_usb_table->setItem(i, usb_column::usb_pid, new QTableWidgetItem(QString::fromStdString(info.pid))); + m_usb_table->setItem(i, usb_column::usb_serial, new QTableWidgetItem(QString::fromStdString(info.serial))); + } + + m_usb_table->resizeColumnsToContents(); + + connect(m_usb_table, &QTableWidget::customContextMenuRequested, this, &vfs_dialog_usb_tab::show_context_menu); + connect(m_usb_table, &QTableWidget::itemDoubleClicked, this, &vfs_dialog_usb_tab::double_clicked_slot); + + QVBoxLayout* vbox = new QVBoxLayout; + vbox->addWidget(m_usb_table); + + setLayout(vbox); +} + +void vfs_dialog_usb_tab::set_settings() const +{ + cfg::map_of_type device_map{}; + + for (int i = 0; i < max_usb_devices; i++) + { + cfg::device_info info{}; + + info.path = m_usb_table->item(i, usb_column::usb_path)->text().toStdString(); + info.vid = m_usb_table->item(i, usb_column::usb_vid)->text().toStdString(); + info.pid = m_usb_table->item(i, usb_column::usb_pid)->text().toStdString(); + info.serial = m_usb_table->item(i, usb_column::usb_serial)->text().toStdString(); + + device_map.emplace(get_device_name(i).toStdString(), std::move(info)); + } + + m_cfg_node->set_map(std::move(device_map)); +} + +void vfs_dialog_usb_tab::reset() const +{ + for (int i = 0; i < max_usb_devices; i++) + { + const QString device_name = get_device_name(i); + const cfg::device_info info = get_device_info(device_name, m_cfg_node->get_default()); + + m_usb_table->item(i, usb_column::usb_path)->setText(QString::fromStdString(info.path)); + m_usb_table->item(i, usb_column::usb_vid)->setText(QString::fromStdString(info.vid)); + m_usb_table->item(i, usb_column::usb_pid)->setText(QString::fromStdString(info.pid)); + m_usb_table->item(i, usb_column::usb_serial)->setText(QString::fromStdString(info.serial)); + } +} + +void vfs_dialog_usb_tab::show_usb_input_dialog(int index) +{ + if (index < 0 || index >= max_usb_devices) + { + return; + } + + const QString device_name = get_device_name(index); + const cfg::device_info default_info = get_device_info(device_name, m_cfg_node->get_default()); + cfg::device_info info{}; + + info.path = m_usb_table->item(index, usb_column::usb_path)->text().toStdString(); + info.vid = m_usb_table->item(index, usb_column::usb_vid)->text().toStdString(); + info.pid = m_usb_table->item(index, usb_column::usb_pid)->text().toStdString(); + info.serial = m_usb_table->item(index, usb_column::usb_serial)->text().toStdString(); + + vfs_dialog_usb_input* input_dialog = new vfs_dialog_usb_input(device_name, default_info, &info, m_gui_settings, this); + if (input_dialog->exec() == QDialog::Accepted) + { + m_usb_table->item(index, usb_column::usb_path)->setText(QString::fromStdString(info.path)); + m_usb_table->item(index, usb_column::usb_vid)->setText(QString::fromStdString(info.vid)); + m_usb_table->item(index, usb_column::usb_pid)->setText(QString::fromStdString(info.pid)); + m_usb_table->item(index, usb_column::usb_serial)->setText(QString::fromStdString(info.serial)); + } + input_dialog->deleteLater(); +} + +void vfs_dialog_usb_tab::show_context_menu(const QPoint& pos) +{ + const int row = m_usb_table->indexAt(pos).row(); + + if (row < 0 || row >= max_usb_devices) + { + return; + } + + QMenu menu{}; + QAction* edit = menu.addAction(tr("&Edit")); + + connect(edit, &QAction::triggered, this, [this, row]() + { + show_usb_input_dialog(row); + }); + + menu.exec(m_usb_table->viewport()->mapToGlobal(pos)); +} + +void vfs_dialog_usb_tab::double_clicked_slot(QTableWidgetItem* item) +{ + if (!item) + { + return; + } + + show_usb_input_dialog(item->row()); +} diff --git a/rpcs3/rpcs3qt/vfs_dialog_usb_tab.h b/rpcs3/rpcs3qt/vfs_dialog_usb_tab.h new file mode 100644 index 0000000000..a07ac040f8 --- /dev/null +++ b/rpcs3/rpcs3qt/vfs_dialog_usb_tab.h @@ -0,0 +1,37 @@ +#pragma once + +#include "util/types.hpp" + +#include "gui_settings.h" + +#include +#include + +#include + +namespace cfg +{ + class device_entry; +} + +class vfs_dialog_usb_tab : public QWidget +{ + Q_OBJECT + +public: + explicit vfs_dialog_usb_tab(cfg::device_entry* cfg_node, std::shared_ptr _gui_settings, QWidget* parent = nullptr); + + void set_settings() const; + + // Reset this tab without saving the settings yet + void reset() const; + +private: + void show_usb_input_dialog(int index); + void show_context_menu(const QPoint& pos); + void double_clicked_slot(QTableWidgetItem* item); + + cfg::device_entry* m_cfg_node; + std::shared_ptr m_gui_settings; + QTableWidget* m_usb_table; +};