WiiPane.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533
  1. // Copyright 2017 Dolphin Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include "DolphinQt/Settings/WiiPane.h"
  4. #include <array>
  5. #include <future>
  6. #include <utility>
  7. #include <QCheckBox>
  8. #include <QComboBox>
  9. #include <QDir>
  10. #include <QGridLayout>
  11. #include <QGroupBox>
  12. #include <QHBoxLayout>
  13. #include <QLabel>
  14. #include <QLineEdit>
  15. #include <QListWidget>
  16. #include <QPushButton>
  17. #include <QSlider>
  18. #include <QSpacerItem>
  19. #include <QStringList>
  20. #include "Common/Config/Config.h"
  21. #include "Common/FatFsUtil.h"
  22. #include "Common/FileUtil.h"
  23. #include "Common/StringUtil.h"
  24. #include "Core/Config/MainSettings.h"
  25. #include "Core/Config/SYSCONFSettings.h"
  26. #include "Core/ConfigManager.h"
  27. #include "Core/Core.h"
  28. #include "Core/System.h"
  29. #include "DolphinQt/QtUtils/DolphinFileDialog.h"
  30. #include "DolphinQt/QtUtils/ModalMessageBox.h"
  31. #include "DolphinQt/QtUtils/NonDefaultQPushButton.h"
  32. #include "DolphinQt/QtUtils/ParallelProgressDialog.h"
  33. #include "DolphinQt/QtUtils/SetWindowDecorations.h"
  34. #include "DolphinQt/QtUtils/SignalBlocking.h"
  35. #include "DolphinQt/Settings.h"
  36. #include "DolphinQt/Settings/USBDeviceAddToWhitelistDialog.h"
  37. #include "UICommon/USBUtils.h"
  38. // SYSCONF uses 0 for bottom and 1 for top, but we place them in
  39. // the other order in the GUI so that Top will be above Bottom,
  40. // matching the respective physical placements of the sensor bar.
  41. // This also matches the layout of the settings in the Wii Menu.
  42. static int TranslateSensorBarPosition(int position)
  43. {
  44. if (position == 0)
  45. return 1;
  46. if (position == 1)
  47. return 0;
  48. return position;
  49. }
  50. namespace
  51. {
  52. struct SDSizeComboEntry
  53. {
  54. u64 size;
  55. const char* name;
  56. };
  57. static constexpr u64 MebibytesToBytes(u64 mebibytes)
  58. {
  59. return mebibytes * 1024u * 1024u;
  60. }
  61. static constexpr u64 GibibytesToBytes(u64 gibibytes)
  62. {
  63. return MebibytesToBytes(gibibytes * 1024u);
  64. }
  65. constexpr std::array sd_size_combo_entries{
  66. SDSizeComboEntry{0, _trans("Auto")},
  67. SDSizeComboEntry{MebibytesToBytes(64), _trans("64 MiB")},
  68. SDSizeComboEntry{MebibytesToBytes(128), _trans("128 MiB")},
  69. SDSizeComboEntry{MebibytesToBytes(256), _trans("256 MiB")},
  70. SDSizeComboEntry{MebibytesToBytes(512), _trans("512 MiB")},
  71. SDSizeComboEntry{GibibytesToBytes(1), _trans("1 GiB")},
  72. SDSizeComboEntry{GibibytesToBytes(2), _trans("2 GiB")},
  73. SDSizeComboEntry{GibibytesToBytes(4), _trans("4 GiB (SDHC)")},
  74. SDSizeComboEntry{GibibytesToBytes(8), _trans("8 GiB (SDHC)")},
  75. SDSizeComboEntry{GibibytesToBytes(16), _trans("16 GiB (SDHC)")},
  76. SDSizeComboEntry{GibibytesToBytes(32), _trans("32 GiB (SDHC)")},
  77. };
  78. } // namespace
  79. WiiPane::WiiPane(QWidget* parent) : QWidget(parent)
  80. {
  81. CreateLayout();
  82. LoadConfig();
  83. ConnectLayout();
  84. ValidateSelectionState();
  85. OnEmulationStateChanged(!Core::IsUninitialized(Core::System::GetInstance()));
  86. }
  87. void WiiPane::CreateLayout()
  88. {
  89. m_main_layout = new QVBoxLayout;
  90. CreateMisc();
  91. CreateSDCard();
  92. CreateWhitelistedUSBPassthroughDevices();
  93. CreateWiiRemoteSettings();
  94. m_main_layout->addStretch(1);
  95. setLayout(m_main_layout);
  96. }
  97. void WiiPane::ConnectLayout()
  98. {
  99. // Misc Settings
  100. connect(m_aspect_ratio_choice, &QComboBox::currentIndexChanged, this, &WiiPane::OnSaveConfig);
  101. connect(m_system_language_choice, &QComboBox::currentIndexChanged, this, &WiiPane::OnSaveConfig);
  102. connect(m_sound_mode_choice, &QComboBox::currentIndexChanged, this, &WiiPane::OnSaveConfig);
  103. connect(m_screensaver_checkbox, &QCheckBox::toggled, this, &WiiPane::OnSaveConfig);
  104. connect(m_pal60_mode_checkbox, &QCheckBox::toggled, this, &WiiPane::OnSaveConfig);
  105. connect(m_connect_keyboard_checkbox, &QCheckBox::toggled, this, &WiiPane::OnSaveConfig);
  106. connect(&Settings::Instance(), &Settings::SDCardInsertionChanged, m_sd_card_checkbox,
  107. &QCheckBox::setChecked);
  108. connect(&Settings::Instance(), &Settings::USBKeyboardConnectionChanged,
  109. m_connect_keyboard_checkbox, &QCheckBox::setChecked);
  110. connect(m_wiilink_checkbox, &QCheckBox::toggled, this, &WiiPane::OnSaveConfig);
  111. // SD Card Settings
  112. connect(m_sd_card_checkbox, &QCheckBox::toggled, this, &WiiPane::OnSaveConfig);
  113. connect(m_allow_sd_writes_checkbox, &QCheckBox::toggled, this, &WiiPane::OnSaveConfig);
  114. connect(m_sync_sd_folder_checkbox, &QCheckBox::toggled, this, &WiiPane::OnSaveConfig);
  115. connect(m_sd_card_size_combo, &QComboBox::currentIndexChanged, this, &WiiPane::OnSaveConfig);
  116. // Whitelisted USB Passthrough Devices
  117. connect(m_whitelist_usb_list, &QListWidget::itemClicked, this, &WiiPane::ValidateSelectionState);
  118. connect(m_whitelist_usb_add_button, &QPushButton::clicked, this,
  119. &WiiPane::OnUSBWhitelistAddButton);
  120. connect(m_whitelist_usb_remove_button, &QPushButton::clicked, this,
  121. &WiiPane::OnUSBWhitelistRemoveButton);
  122. // Wii Remote Settings
  123. connect(m_wiimote_ir_sensor_position, &QComboBox::currentIndexChanged, this,
  124. &WiiPane::OnSaveConfig);
  125. connect(m_wiimote_ir_sensitivity, &QSlider::valueChanged, this, &WiiPane::OnSaveConfig);
  126. connect(m_wiimote_speaker_volume, &QSlider::valueChanged, this, &WiiPane::OnSaveConfig);
  127. connect(m_wiimote_motor, &QCheckBox::toggled, this, &WiiPane::OnSaveConfig);
  128. // Emulation State
  129. connect(&Settings::Instance(), &Settings::EmulationStateChanged, this, [this](Core::State state) {
  130. OnEmulationStateChanged(state != Core::State::Uninitialized);
  131. });
  132. }
  133. void WiiPane::CreateMisc()
  134. {
  135. auto* misc_settings_group = new QGroupBox(tr("Misc Settings"));
  136. auto* misc_settings_group_layout = new QGridLayout();
  137. misc_settings_group->setLayout(misc_settings_group_layout);
  138. m_main_layout->addWidget(misc_settings_group);
  139. m_pal60_mode_checkbox = new QCheckBox(tr("Use PAL60 Mode (EuRGB60)"));
  140. m_screensaver_checkbox = new QCheckBox(tr("Enable Screen Saver"));
  141. m_wiilink_checkbox = new QCheckBox(tr("Enable WiiConnect24 via WiiLink"));
  142. m_connect_keyboard_checkbox = new QCheckBox(tr("Connect USB Keyboard"));
  143. m_aspect_ratio_choice_label = new QLabel(tr("Aspect Ratio:"));
  144. m_aspect_ratio_choice = new QComboBox();
  145. m_aspect_ratio_choice->addItem(tr("4:3"));
  146. m_aspect_ratio_choice->addItem(tr("16:9"));
  147. m_system_language_choice_label = new QLabel(tr("System Language:"));
  148. m_system_language_choice = new QComboBox();
  149. m_system_language_choice->addItem(tr("Japanese"));
  150. m_system_language_choice->addItem(tr("English"));
  151. m_system_language_choice->addItem(tr("German"));
  152. m_system_language_choice->addItem(tr("French"));
  153. m_system_language_choice->addItem(tr("Spanish"));
  154. m_system_language_choice->addItem(tr("Italian"));
  155. m_system_language_choice->addItem(tr("Dutch"));
  156. m_system_language_choice->addItem(tr("Simplified Chinese"));
  157. m_system_language_choice->addItem(tr("Traditional Chinese"));
  158. m_system_language_choice->addItem(tr("Korean"));
  159. m_sound_mode_choice_label = new QLabel(tr("Sound:"));
  160. m_sound_mode_choice = new QComboBox();
  161. m_sound_mode_choice->addItem(tr("Mono"));
  162. m_sound_mode_choice->addItem(tr("Stereo"));
  163. // i18n: Surround audio (Dolby Pro Logic II)
  164. m_sound_mode_choice->addItem(tr("Surround"));
  165. m_pal60_mode_checkbox->setToolTip(tr("Sets the Wii display mode to 60Hz (480i) instead of 50Hz "
  166. "(576i) for PAL games.\nMay not work for all games."));
  167. m_screensaver_checkbox->setToolTip(tr("Dims the screen after five minutes of inactivity."));
  168. m_wiilink_checkbox->setToolTip(tr(
  169. "Enables the WiiLink service for WiiConnect24 channels.\nWiiLink is an alternate provider "
  170. "for the discontinued WiiConnect24 Channels such as the Forecast and Nintendo Channels\nRead "
  171. "the Terms of Service at: https://www.wiilink24.com/tos"));
  172. m_system_language_choice->setToolTip(tr("Sets the Wii system language."));
  173. m_connect_keyboard_checkbox->setToolTip(tr("May cause slow down in Wii Menu and some games."));
  174. misc_settings_group_layout->addWidget(m_pal60_mode_checkbox, 0, 0, 1, 1);
  175. misc_settings_group_layout->addWidget(m_connect_keyboard_checkbox, 0, 1, 1, 1);
  176. misc_settings_group_layout->addWidget(m_screensaver_checkbox, 1, 0, 1, 1);
  177. misc_settings_group_layout->addWidget(m_wiilink_checkbox, 1, 1, 1, 1);
  178. misc_settings_group_layout->addWidget(m_aspect_ratio_choice_label, 2, 0, 1, 1);
  179. misc_settings_group_layout->addWidget(m_aspect_ratio_choice, 2, 1, 1, 1);
  180. misc_settings_group_layout->addWidget(m_system_language_choice_label, 3, 0, 1, 1);
  181. misc_settings_group_layout->addWidget(m_system_language_choice, 3, 1, 1, 1);
  182. misc_settings_group_layout->addWidget(m_sound_mode_choice_label, 4, 0, 1, 1);
  183. misc_settings_group_layout->addWidget(m_sound_mode_choice, 4, 1, 1, 1);
  184. }
  185. void WiiPane::CreateSDCard()
  186. {
  187. auto* sd_settings_group = new QGroupBox(tr("SD Card Settings"));
  188. auto* sd_settings_group_layout = new QGridLayout();
  189. sd_settings_group->setLayout(sd_settings_group_layout);
  190. m_main_layout->addWidget(sd_settings_group);
  191. int row = 0;
  192. m_sd_card_checkbox = new QCheckBox(tr("Insert SD Card"));
  193. m_sd_card_checkbox->setToolTip(tr("Supports SD and SDHC. Default size is 128 MB."));
  194. m_allow_sd_writes_checkbox = new QCheckBox(tr("Allow Writes to SD Card"));
  195. sd_settings_group_layout->addWidget(m_sd_card_checkbox, row, 0, 1, 1);
  196. sd_settings_group_layout->addWidget(m_allow_sd_writes_checkbox, row, 1, 1, 1);
  197. ++row;
  198. {
  199. QHBoxLayout* hlayout = new QHBoxLayout;
  200. m_sd_raw_edit = new QLineEdit(QString::fromStdString(File::GetUserPath(F_WIISDCARDIMAGE_IDX)));
  201. connect(m_sd_raw_edit, &QLineEdit::editingFinished,
  202. [this] { SetSDRaw(m_sd_raw_edit->text()); });
  203. QPushButton* sdcard_open = new NonDefaultQPushButton(QStringLiteral("..."));
  204. connect(sdcard_open, &QPushButton::clicked, this, &WiiPane::BrowseSDRaw);
  205. hlayout->addWidget(new QLabel(tr("SD Card Path:")));
  206. hlayout->addWidget(m_sd_raw_edit);
  207. hlayout->addWidget(sdcard_open);
  208. sd_settings_group_layout->addLayout(hlayout, row, 0, 1, 2);
  209. ++row;
  210. }
  211. m_sync_sd_folder_checkbox = new QCheckBox(tr("Automatically Sync with Folder"));
  212. m_sync_sd_folder_checkbox->setToolTip(
  213. tr("Synchronizes the SD Card with the SD Sync Folder when starting and ending emulation."));
  214. sd_settings_group_layout->addWidget(m_sync_sd_folder_checkbox, row, 0, 1, 2);
  215. ++row;
  216. {
  217. QHBoxLayout* hlayout = new QHBoxLayout;
  218. m_sd_sync_folder_edit =
  219. new QLineEdit(QString::fromStdString(File::GetUserPath(D_WIISDCARDSYNCFOLDER_IDX)));
  220. connect(m_sd_sync_folder_edit, &QLineEdit::editingFinished,
  221. [this] { SetSDSyncFolder(m_sd_sync_folder_edit->text()); });
  222. QPushButton* sdcard_open = new NonDefaultQPushButton(QStringLiteral("..."));
  223. connect(sdcard_open, &QPushButton::clicked, this, &WiiPane::BrowseSDSyncFolder);
  224. hlayout->addWidget(new QLabel(tr("SD Sync Folder:")));
  225. hlayout->addWidget(m_sd_sync_folder_edit);
  226. hlayout->addWidget(sdcard_open);
  227. sd_settings_group_layout->addLayout(hlayout, row, 0, 1, 2);
  228. ++row;
  229. }
  230. m_sd_card_size_combo = new QComboBox();
  231. for (size_t i = 0; i < sd_size_combo_entries.size(); ++i)
  232. m_sd_card_size_combo->addItem(tr(sd_size_combo_entries[i].name));
  233. sd_settings_group_layout->addWidget(new QLabel(tr("SD Card File Size:")), row, 0);
  234. sd_settings_group_layout->addWidget(m_sd_card_size_combo, row, 1);
  235. ++row;
  236. m_sd_pack_button = new NonDefaultQPushButton(tr(Common::SD_PACK_TEXT));
  237. m_sd_unpack_button = new NonDefaultQPushButton(tr(Common::SD_UNPACK_TEXT));
  238. connect(m_sd_pack_button, &QPushButton::clicked, [this] {
  239. auto result = ModalMessageBox::warning(
  240. this, tr(Common::SD_PACK_TEXT),
  241. tr("You are about to pack the content of the folder at %1 into the file at %2. All "
  242. "current content of the file will be deleted. Are you sure you want to continue?")
  243. .arg(QString::fromStdString(File::GetUserPath(D_WIISDCARDSYNCFOLDER_IDX)))
  244. .arg(QString::fromStdString(File::GetUserPath(F_WIISDCARDIMAGE_IDX))),
  245. QMessageBox::Yes | QMessageBox::No);
  246. if (result == QMessageBox::Yes)
  247. {
  248. ParallelProgressDialog progress_dialog(tr("Converting..."), tr("Cancel"), 0, 0, this);
  249. progress_dialog.GetRaw()->setWindowModality(Qt::WindowModal);
  250. progress_dialog.GetRaw()->setWindowTitle(tr("Progress"));
  251. auto success = std::async(std::launch::async, [&] {
  252. const bool good = Common::SyncSDFolderToSDImage(
  253. [&progress_dialog]() { return progress_dialog.WasCanceled(); }, false);
  254. progress_dialog.Reset();
  255. return good;
  256. });
  257. SetQWidgetWindowDecorations(progress_dialog.GetRaw());
  258. progress_dialog.GetRaw()->exec();
  259. if (!success.get())
  260. ModalMessageBox::warning(this, tr(Common::SD_PACK_TEXT), tr("Conversion failed."));
  261. }
  262. });
  263. connect(m_sd_unpack_button, &QPushButton::clicked, [this] {
  264. auto result = ModalMessageBox::warning(
  265. this, tr(Common::SD_UNPACK_TEXT),
  266. tr("You are about to unpack the content of the file at %2 into the folder at %1. All "
  267. "current content of the folder will be deleted. Are you sure you want to continue?")
  268. .arg(QString::fromStdString(File::GetUserPath(D_WIISDCARDSYNCFOLDER_IDX)))
  269. .arg(QString::fromStdString(File::GetUserPath(F_WIISDCARDIMAGE_IDX))),
  270. QMessageBox::Yes | QMessageBox::No);
  271. if (result == QMessageBox::Yes)
  272. {
  273. ParallelProgressDialog progress_dialog(tr("Converting..."), tr("Cancel"), 0, 0, this);
  274. progress_dialog.GetRaw()->setWindowModality(Qt::WindowModal);
  275. progress_dialog.GetRaw()->setWindowTitle(tr("Progress"));
  276. auto success = std::async(std::launch::async, [&] {
  277. const bool good = Common::SyncSDImageToSDFolder(
  278. [&progress_dialog]() { return progress_dialog.WasCanceled(); });
  279. progress_dialog.Reset();
  280. return good;
  281. });
  282. SetQWidgetWindowDecorations(progress_dialog.GetRaw());
  283. progress_dialog.GetRaw()->exec();
  284. if (!success.get())
  285. ModalMessageBox::warning(this, tr(Common::SD_UNPACK_TEXT), tr("Conversion failed."));
  286. }
  287. });
  288. sd_settings_group_layout->addWidget(m_sd_pack_button, row, 0, 1, 1);
  289. sd_settings_group_layout->addWidget(m_sd_unpack_button, row, 1, 1, 1);
  290. ++row;
  291. }
  292. void WiiPane::CreateWhitelistedUSBPassthroughDevices()
  293. {
  294. m_whitelist_usb_list = new QListWidget();
  295. m_whitelist_usb_add_button = new NonDefaultQPushButton(tr("Add..."));
  296. m_whitelist_usb_remove_button = new NonDefaultQPushButton(tr("Remove"));
  297. QHBoxLayout* hlayout = new QHBoxLayout;
  298. hlayout->addStretch();
  299. hlayout->addWidget(m_whitelist_usb_add_button);
  300. hlayout->addWidget(m_whitelist_usb_remove_button);
  301. QVBoxLayout* vlayout = new QVBoxLayout;
  302. vlayout->addWidget(m_whitelist_usb_list);
  303. vlayout->addLayout(hlayout);
  304. auto* whitelisted_usb_passthrough_devices_group =
  305. new QGroupBox(tr("Whitelisted USB Passthrough Devices"));
  306. whitelisted_usb_passthrough_devices_group->setLayout(vlayout);
  307. m_main_layout->addWidget(whitelisted_usb_passthrough_devices_group);
  308. }
  309. void WiiPane::CreateWiiRemoteSettings()
  310. {
  311. auto* wii_remote_settings_group = new QGroupBox(tr("Wii Remote Settings"));
  312. auto* wii_remote_settings_group_layout = new QGridLayout();
  313. wii_remote_settings_group->setLayout(wii_remote_settings_group_layout);
  314. m_main_layout->addWidget(wii_remote_settings_group);
  315. m_wiimote_motor = new QCheckBox(tr("Enable Rumble"));
  316. m_wiimote_sensor_position_label = new QLabel(tr("Sensor Bar Position:"));
  317. m_wiimote_ir_sensor_position = new QComboBox();
  318. m_wiimote_ir_sensor_position->addItem(tr("Top"));
  319. m_wiimote_ir_sensor_position->addItem(tr("Bottom"));
  320. // IR Sensitivity Slider
  321. // i18n: IR stands for infrared and refers to the pointer functionality of Wii Remotes
  322. m_wiimote_ir_sensitivity_label = new QLabel(tr("IR Sensitivity:"));
  323. m_wiimote_ir_sensitivity = new QSlider(Qt::Horizontal);
  324. // Wii menu saves values from 1 to 5.
  325. m_wiimote_ir_sensitivity->setMinimum(1);
  326. m_wiimote_ir_sensitivity->setMaximum(5);
  327. // Speaker Volume Slider
  328. m_wiimote_speaker_volume_label = new QLabel(tr("Speaker Volume:"));
  329. m_wiimote_speaker_volume = new QSlider(Qt::Horizontal);
  330. m_wiimote_speaker_volume->setMinimum(0);
  331. m_wiimote_speaker_volume->setMaximum(127);
  332. wii_remote_settings_group_layout->addWidget(m_wiimote_sensor_position_label, 0, 0);
  333. wii_remote_settings_group_layout->addWidget(m_wiimote_ir_sensor_position, 0, 1);
  334. wii_remote_settings_group_layout->addWidget(m_wiimote_ir_sensitivity_label, 1, 0);
  335. wii_remote_settings_group_layout->addWidget(m_wiimote_ir_sensitivity, 1, 1);
  336. wii_remote_settings_group_layout->addWidget(m_wiimote_speaker_volume_label, 2, 0);
  337. wii_remote_settings_group_layout->addWidget(m_wiimote_speaker_volume, 2, 1);
  338. wii_remote_settings_group_layout->addWidget(m_wiimote_motor, 3, 0, 1, -1);
  339. }
  340. void WiiPane::OnEmulationStateChanged(bool running)
  341. {
  342. m_screensaver_checkbox->setEnabled(!running);
  343. m_pal60_mode_checkbox->setEnabled(!running);
  344. m_system_language_choice->setEnabled(!running);
  345. m_aspect_ratio_choice->setEnabled(!running);
  346. m_sound_mode_choice->setEnabled(!running);
  347. m_sd_pack_button->setEnabled(!running);
  348. m_sd_unpack_button->setEnabled(!running);
  349. m_wiimote_motor->setEnabled(!running);
  350. m_wiimote_speaker_volume->setEnabled(!running);
  351. m_wiimote_ir_sensitivity->setEnabled(!running);
  352. m_wiimote_ir_sensor_position->setEnabled(!running);
  353. m_wiilink_checkbox->setEnabled(!running);
  354. }
  355. void WiiPane::LoadConfig()
  356. {
  357. m_screensaver_checkbox->setChecked(Config::Get(Config::SYSCONF_SCREENSAVER));
  358. m_pal60_mode_checkbox->setChecked(Config::Get(Config::SYSCONF_PAL60));
  359. m_connect_keyboard_checkbox->setChecked(Settings::Instance().IsUSBKeyboardConnected());
  360. m_aspect_ratio_choice->setCurrentIndex(Config::Get(Config::SYSCONF_WIDESCREEN));
  361. m_system_language_choice->setCurrentIndex(Config::Get(Config::SYSCONF_LANGUAGE));
  362. m_sound_mode_choice->setCurrentIndex(Config::Get(Config::SYSCONF_SOUND_MODE));
  363. m_wiilink_checkbox->setChecked(Config::Get(Config::MAIN_WII_WIILINK_ENABLE));
  364. m_sd_card_checkbox->setChecked(Settings::Instance().IsSDCardInserted());
  365. m_allow_sd_writes_checkbox->setChecked(Config::Get(Config::MAIN_ALLOW_SD_WRITES));
  366. m_sync_sd_folder_checkbox->setChecked(Config::Get(Config::MAIN_WII_SD_CARD_ENABLE_FOLDER_SYNC));
  367. const u64 sd_card_size = Config::Get(Config::MAIN_WII_SD_CARD_FILESIZE);
  368. for (size_t i = 0; i < sd_size_combo_entries.size(); ++i)
  369. {
  370. if (sd_size_combo_entries[i].size == sd_card_size)
  371. m_sd_card_size_combo->setCurrentIndex(static_cast<int>(i));
  372. }
  373. PopulateUSBPassthroughListWidget();
  374. m_wiimote_ir_sensor_position->setCurrentIndex(
  375. TranslateSensorBarPosition(Config::Get(Config::SYSCONF_SENSOR_BAR_POSITION)));
  376. m_wiimote_ir_sensitivity->setValue(Config::Get(Config::SYSCONF_SENSOR_BAR_SENSITIVITY));
  377. m_wiimote_speaker_volume->setValue(Config::Get(Config::SYSCONF_SPEAKER_VOLUME));
  378. m_wiimote_motor->setChecked(Config::Get(Config::SYSCONF_WIIMOTE_MOTOR));
  379. }
  380. void WiiPane::OnSaveConfig()
  381. {
  382. Config::ConfigChangeCallbackGuard config_guard;
  383. Config::SetBase(Config::SYSCONF_SCREENSAVER, m_screensaver_checkbox->isChecked());
  384. Config::SetBase(Config::SYSCONF_PAL60, m_pal60_mode_checkbox->isChecked());
  385. Settings::Instance().SetUSBKeyboardConnected(m_connect_keyboard_checkbox->isChecked());
  386. Config::SetBase<u32>(Config::SYSCONF_SENSOR_BAR_POSITION,
  387. TranslateSensorBarPosition(m_wiimote_ir_sensor_position->currentIndex()));
  388. Config::SetBase<u32>(Config::SYSCONF_SENSOR_BAR_SENSITIVITY, m_wiimote_ir_sensitivity->value());
  389. Config::SetBase<u32>(Config::SYSCONF_SPEAKER_VOLUME, m_wiimote_speaker_volume->value());
  390. Config::SetBase<u32>(Config::SYSCONF_LANGUAGE, m_system_language_choice->currentIndex());
  391. Config::SetBase<bool>(Config::SYSCONF_WIDESCREEN, m_aspect_ratio_choice->currentIndex());
  392. Config::SetBase<u32>(Config::SYSCONF_SOUND_MODE, m_sound_mode_choice->currentIndex());
  393. Config::SetBase(Config::SYSCONF_WIIMOTE_MOTOR, m_wiimote_motor->isChecked());
  394. Config::SetBase(Config::MAIN_WII_WIILINK_ENABLE, m_wiilink_checkbox->isChecked());
  395. Settings::Instance().SetSDCardInserted(m_sd_card_checkbox->isChecked());
  396. Config::SetBase(Config::MAIN_ALLOW_SD_WRITES, m_allow_sd_writes_checkbox->isChecked());
  397. Config::SetBase(Config::MAIN_WII_SD_CARD_ENABLE_FOLDER_SYNC,
  398. m_sync_sd_folder_checkbox->isChecked());
  399. const int sd_card_size_index = m_sd_card_size_combo->currentIndex();
  400. if (sd_card_size_index >= 0 &&
  401. static_cast<size_t>(sd_card_size_index) < sd_size_combo_entries.size())
  402. {
  403. Config::SetBase(Config::MAIN_WII_SD_CARD_FILESIZE,
  404. sd_size_combo_entries[sd_card_size_index].size);
  405. }
  406. }
  407. void WiiPane::ValidateSelectionState()
  408. {
  409. m_whitelist_usb_remove_button->setEnabled(m_whitelist_usb_list->currentIndex().isValid());
  410. }
  411. void WiiPane::OnUSBWhitelistAddButton()
  412. {
  413. USBDeviceAddToWhitelistDialog usb_whitelist_dialog(this);
  414. connect(&usb_whitelist_dialog, &USBDeviceAddToWhitelistDialog::accepted, this,
  415. &WiiPane::PopulateUSBPassthroughListWidget);
  416. SetQWidgetWindowDecorations(&usb_whitelist_dialog);
  417. usb_whitelist_dialog.exec();
  418. }
  419. void WiiPane::OnUSBWhitelistRemoveButton()
  420. {
  421. QString device = m_whitelist_usb_list->currentItem()->text().left(9);
  422. QStringList split = device.split(QString::fromStdString(":"));
  423. QString vid = QString(split[0]);
  424. QString pid = QString(split[1]);
  425. const u16 vid_u16 = static_cast<u16>(std::stoul(vid.toStdString(), nullptr, 16));
  426. const u16 pid_u16 = static_cast<u16>(std::stoul(pid.toStdString(), nullptr, 16));
  427. auto whitelist = Config::GetUSBDeviceWhitelist();
  428. whitelist.erase({vid_u16, pid_u16});
  429. Config::SetUSBDeviceWhitelist(whitelist);
  430. PopulateUSBPassthroughListWidget();
  431. }
  432. void WiiPane::PopulateUSBPassthroughListWidget()
  433. {
  434. m_whitelist_usb_list->clear();
  435. auto whitelist = Config::GetUSBDeviceWhitelist();
  436. for (const auto& device : whitelist)
  437. {
  438. QListWidgetItem* usb_lwi =
  439. new QListWidgetItem(QString::fromStdString(USBUtils::GetDeviceName(device)));
  440. m_whitelist_usb_list->addItem(usb_lwi);
  441. }
  442. ValidateSelectionState();
  443. }
  444. void WiiPane::BrowseSDRaw()
  445. {
  446. QString file = QDir::toNativeSeparators(DolphinFileDialog::getOpenFileName(
  447. this, tr("Select SD Card Image"),
  448. QString::fromStdString(Config::Get(Config::MAIN_WII_SD_CARD_IMAGE_PATH)),
  449. tr("SD Card Image (*.raw);;"
  450. "All Files (*)")));
  451. if (!file.isEmpty())
  452. SetSDRaw(file);
  453. }
  454. void WiiPane::SetSDRaw(const QString& path)
  455. {
  456. Config::SetBase(Config::MAIN_WII_SD_CARD_IMAGE_PATH, path.toStdString());
  457. SignalBlocking(m_sd_raw_edit)->setText(path);
  458. }
  459. void WiiPane::BrowseSDSyncFolder()
  460. {
  461. QString file = QDir::toNativeSeparators(DolphinFileDialog::getExistingDirectory(
  462. this, tr("Select a Folder to Sync with the SD Card Image"),
  463. QString::fromStdString(Config::Get(Config::MAIN_WII_SD_CARD_SYNC_FOLDER_PATH))));
  464. if (!file.isEmpty())
  465. SetSDSyncFolder(file);
  466. }
  467. void WiiPane::SetSDSyncFolder(const QString& path)
  468. {
  469. Config::SetBase(Config::MAIN_WII_SD_CARD_SYNC_FOLDER_PATH, path.toStdString());
  470. SignalBlocking(m_sd_sync_folder_edit)->setText(path);
  471. }